2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import static android.Manifest.permission.CHANGE_CONFIGURATION;
20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25 import static android.Manifest.permission.READ_FRAME_BUFFER;
26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
32 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
35 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
36 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
37 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
38 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
39 import static android.content.pm.PackageManager.GET_PROVIDERS;
40 import static android.content.pm.PackageManager.MATCH_ANY_USER;
41 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
43 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
44 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
45 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
46 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
47 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
49 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
50 import static android.os.Build.VERSION_CODES.N;
51 import static android.os.Process.BLUETOOTH_UID;
52 import static android.os.Process.FIRST_APPLICATION_UID;
53 import static android.os.Process.FIRST_ISOLATED_UID;
54 import static android.os.Process.LAST_ISOLATED_UID;
55 import static android.os.Process.NFC_UID;
56 import static android.os.Process.PHONE_UID;
57 import static android.os.Process.PROC_CHAR;
58 import static android.os.Process.PROC_OUT_LONG;
59 import static android.os.Process.PROC_PARENS;
60 import static android.os.Process.PROC_SPACE_TERM;
61 import static android.os.Process.ProcessStartResult;
62 import static android.os.Process.ROOT_UID;
63 import static android.os.Process.SCHED_FIFO;
64 import static android.os.Process.SCHED_OTHER;
65 import static android.os.Process.SCHED_RESET_ON_FORK;
66 import static android.os.Process.SHELL_UID;
67 import static android.os.Process.SIGNAL_QUIT;
68 import static android.os.Process.SIGNAL_USR1;
69 import static android.os.Process.SYSTEM_UID;
70 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
71 import static android.os.Process.THREAD_GROUP_DEFAULT;
72 import static android.os.Process.THREAD_GROUP_TOP_APP;
73 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
74 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
75 import static android.os.Process.getFreeMemory;
76 import static android.os.Process.getTotalMemory;
77 import static android.os.Process.isThreadInProcess;
78 import static android.os.Process.killProcess;
79 import static android.os.Process.killProcessQuiet;
80 import static android.os.Process.myPid;
81 import static android.os.Process.myUid;
82 import static android.os.Process.readProcFile;
83 import static android.os.Process.removeAllProcessGroups;
84 import static android.os.Process.sendSignal;
85 import static android.os.Process.setProcessGroup;
86 import static android.os.Process.setThreadPriority;
87 import static android.os.Process.setThreadScheduler;
88 import static android.os.Process.startWebView;
89 import static android.os.Process.zygoteProcess;
90 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
91 import static android.provider.Settings.Global.DEBUG_APP;
92 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
94 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
95 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
96 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
97 import static android.provider.Settings.System.FONT_SCALE;
98 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
99 import static android.text.format.DateUtils.DAY_IN_MILLIS;
100 import static android.view.Display.DEFAULT_DISPLAY;
101 import static android.view.Display.INVALID_DISPLAY;
102 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
103 import static com.android.internal.util.XmlUtils.readIntAttribute;
104 import static com.android.internal.util.XmlUtils.readLongAttribute;
105 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
106 import static com.android.internal.util.XmlUtils.writeIntAttribute;
107 import static com.android.internal.util.XmlUtils.writeLongAttribute;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
165 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
167 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188 import static org.xmlpull.v1.XmlPullParser.START_TAG;
190 import android.Manifest;
191 import android.Manifest.permission;
192 import android.annotation.NonNull;
193 import android.annotation.Nullable;
194 import android.annotation.UserIdInt;
195 import android.app.Activity;
196 import android.app.ActivityManager;
197 import android.app.ActivityManager.RunningTaskInfo;
198 import android.app.ActivityManager.StackId;
199 import android.app.ActivityManager.StackInfo;
200 import android.app.ActivityManager.TaskSnapshot;
201 import android.app.ActivityManager.TaskThumbnailInfo;
202 import android.app.ActivityManagerInternal;
203 import android.app.ActivityManagerInternal.SleepToken;
204 import android.app.ActivityOptions;
205 import android.app.ActivityThread;
206 import android.app.AlertDialog;
207 import android.app.AppGlobals;
208 import android.app.AppOpsManager;
209 import android.app.ApplicationErrorReport;
210 import android.app.ApplicationThreadConstants;
211 import android.app.BroadcastOptions;
212 import android.app.ContentProviderHolder;
213 import android.app.Dialog;
214 import android.app.IActivityController;
215 import android.app.IActivityManager;
216 import android.app.IAppTask;
217 import android.app.IApplicationThread;
218 import android.app.IInstrumentationWatcher;
219 import android.app.INotificationManager;
220 import android.app.IProcessObserver;
221 import android.app.IServiceConnection;
222 import android.app.IStopUserCallback;
223 import android.app.ITaskStackListener;
224 import android.app.IUiAutomationConnection;
225 import android.app.IUidObserver;
226 import android.app.IUserSwitchObserver;
227 import android.app.Instrumentation;
228 import android.app.Notification;
229 import android.app.NotificationManager;
230 import android.app.PendingIntent;
231 import android.app.PictureInPictureParams;
232 import android.app.ProfilerInfo;
233 import android.app.RemoteAction;
234 import android.app.WaitResult;
235 import android.app.admin.DevicePolicyManager;
236 import android.app.assist.AssistContent;
237 import android.app.assist.AssistStructure;
238 import android.app.backup.IBackupManager;
239 import android.app.usage.UsageEvents;
240 import android.app.usage.UsageStatsManagerInternal;
241 import android.appwidget.AppWidgetManager;
242 import android.content.ActivityNotFoundException;
243 import android.content.BroadcastReceiver;
244 import android.content.ClipData;
245 import android.content.ComponentCallbacks2;
246 import android.content.ComponentName;
247 import android.content.ContentProvider;
248 import android.content.ContentResolver;
249 import android.content.Context;
250 import android.content.DialogInterface;
251 import android.content.IContentProvider;
252 import android.content.IIntentReceiver;
253 import android.content.IIntentSender;
254 import android.content.Intent;
255 import android.content.IntentFilter;
256 import android.content.pm.ActivityInfo;
257 import android.content.pm.ApplicationInfo;
258 import android.content.pm.ConfigurationInfo;
259 import android.content.pm.IPackageDataObserver;
260 import android.content.pm.IPackageManager;
261 import android.content.pm.InstrumentationInfo;
262 import android.content.pm.PackageInfo;
263 import android.content.pm.PackageManager;
264 import android.content.pm.PackageManager.NameNotFoundException;
265 import android.content.pm.PackageManagerInternal;
266 import android.content.pm.ParceledListSlice;
267 import android.content.pm.PathPermission;
268 import android.content.pm.PermissionInfo;
269 import android.content.pm.ProviderInfo;
270 import android.content.pm.ResolveInfo;
271 import android.content.pm.SELinuxUtil;
272 import android.content.pm.ServiceInfo;
273 import android.content.pm.UserInfo;
274 import android.content.res.CompatibilityInfo;
275 import android.content.res.Configuration;
276 import android.content.res.Resources;
277 import android.database.ContentObserver;
278 import android.graphics.Bitmap;
279 import android.graphics.Point;
280 import android.graphics.Rect;
281 import android.location.LocationManager;
282 import android.media.audiofx.AudioEffect;
283 import android.metrics.LogMaker;
284 import android.net.Proxy;
285 import android.net.ProxyInfo;
286 import android.net.Uri;
287 import android.os.BatteryStats;
288 import android.os.Binder;
289 import android.os.Build;
290 import android.os.Bundle;
291 import android.os.Debug;
292 import android.os.DropBoxManager;
293 import android.os.Environment;
294 import android.os.FactoryTest;
295 import android.os.FileObserver;
296 import android.os.FileUtils;
297 import android.os.Handler;
298 import android.os.IBinder;
299 import android.os.IDeviceIdentifiersPolicyService;
300 import android.os.IPermissionController;
301 import android.os.IProcessInfoService;
302 import android.os.IProgressListener;
303 import android.os.LocaleList;
304 import android.os.Looper;
305 import android.os.Message;
306 import android.os.Parcel;
307 import android.os.ParcelFileDescriptor;
308 import android.os.PersistableBundle;
309 import android.os.PowerManager;
310 import android.os.PowerManagerInternal;
311 import android.os.Process;
312 import android.os.RemoteCallbackList;
313 import android.os.RemoteException;
314 import android.os.ResultReceiver;
315 import android.os.ServiceManager;
316 import android.os.ShellCallback;
317 import android.os.StrictMode;
318 import android.os.SystemClock;
319 import android.os.SystemProperties;
320 import android.os.Trace;
321 import android.os.TransactionTooLargeException;
322 import android.os.UpdateLock;
323 import android.os.UserHandle;
324 import android.os.UserManager;
325 import android.os.WorkSource;
326 import android.os.storage.IStorageManager;
327 import android.os.storage.StorageManager;
328 import android.os.storage.StorageManagerInternal;
329 import android.provider.Downloads;
330 import android.provider.Settings;
331 import android.service.voice.IVoiceInteractionSession;
332 import android.service.voice.VoiceInteractionManagerInternal;
333 import android.service.voice.VoiceInteractionSession;
334 import android.telecom.TelecomManager;
335 import android.text.TextUtils;
336 import android.text.format.DateUtils;
337 import android.text.format.Time;
338 import android.text.style.SuggestionSpan;
339 import android.util.ArrayMap;
340 import android.util.ArraySet;
341 import android.util.AtomicFile;
342 import android.util.TimingsTraceLog;
343 import android.util.DebugUtils;
344 import android.util.DisplayMetrics;
345 import android.util.EventLog;
346 import android.util.Log;
347 import android.util.Pair;
348 import android.util.PrintWriterPrinter;
349 import android.util.Slog;
350 import android.util.SparseArray;
351 import android.util.SparseIntArray;
352 import android.util.TimeUtils;
353 import android.util.Xml;
354 import android.view.Gravity;
355 import android.view.LayoutInflater;
356 import android.view.View;
357 import android.view.WindowManager;
359 import com.android.server.job.JobSchedulerInternal;
360 import com.google.android.collect.Lists;
361 import com.google.android.collect.Maps;
363 import com.android.internal.R;
364 import com.android.internal.annotations.GuardedBy;
365 import com.android.internal.annotations.VisibleForTesting;
366 import com.android.internal.app.AssistUtils;
367 import com.android.internal.app.DumpHeapActivity;
368 import com.android.internal.app.IAppOpsCallback;
369 import com.android.internal.app.IAppOpsService;
370 import com.android.internal.app.IVoiceInteractor;
371 import com.android.internal.app.ProcessMap;
372 import com.android.internal.app.SystemUserHomeActivity;
373 import com.android.internal.app.procstats.ProcessStats;
374 import com.android.internal.logging.MetricsLogger;
375 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
376 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
377 import com.android.internal.notification.SystemNotificationChannels;
378 import com.android.internal.os.BackgroundThread;
379 import com.android.internal.os.BatteryStatsImpl;
380 import com.android.internal.os.IResultReceiver;
381 import com.android.internal.os.ProcessCpuTracker;
382 import com.android.internal.os.TransferPipe;
383 import com.android.internal.os.Zygote;
384 import com.android.internal.policy.IKeyguardDismissCallback;
385 import com.android.internal.telephony.TelephonyIntents;
386 import com.android.internal.util.ArrayUtils;
387 import com.android.internal.util.DumpUtils;
388 import com.android.internal.util.FastPrintWriter;
389 import com.android.internal.util.FastXmlSerializer;
390 import com.android.internal.util.MemInfoReader;
391 import com.android.internal.util.Preconditions;
392 import com.android.server.AppOpsService;
393 import com.android.server.AttributeCache;
394 import com.android.server.DeviceIdleController;
395 import com.android.server.IntentResolver;
396 import com.android.server.LocalServices;
397 import com.android.server.LockGuard;
398 import com.android.server.NetworkManagementInternal;
399 import com.android.server.RescueParty;
400 import com.android.server.ServiceThread;
401 import com.android.server.SystemConfig;
402 import com.android.server.SystemService;
403 import com.android.server.SystemServiceManager;
404 import com.android.server.ThreadPriorityBooster;
405 import com.android.server.Watchdog;
406 import com.android.server.am.ActivityStack.ActivityState;
407 import com.android.server.firewall.IntentFirewall;
408 import com.android.server.pm.Installer;
409 import com.android.server.pm.Installer.InstallerException;
410 import com.android.server.statusbar.StatusBarManagerInternal;
411 import com.android.server.vr.VrManagerInternal;
412 import com.android.server.wm.PinnedStackWindowController;
413 import com.android.server.wm.WindowManagerService;
415 import java.text.SimpleDateFormat;
416 import org.xmlpull.v1.XmlPullParser;
417 import org.xmlpull.v1.XmlPullParserException;
418 import org.xmlpull.v1.XmlSerializer;
421 import java.io.FileDescriptor;
422 import java.io.FileInputStream;
423 import java.io.FileNotFoundException;
424 import java.io.FileOutputStream;
425 import java.io.IOException;
426 import java.io.InputStreamReader;
427 import java.io.PrintWriter;
428 import java.io.StringWriter;
429 import java.io.UnsupportedEncodingException;
430 import java.lang.ref.WeakReference;
431 import java.nio.charset.StandardCharsets;
432 import java.text.DateFormat;
433 import java.util.ArrayList;
434 import java.util.Arrays;
435 import java.util.Collections;
436 import java.util.Comparator;
437 import java.util.Date;
438 import java.util.HashMap;
439 import java.util.HashSet;
440 import java.util.Iterator;
441 import java.util.List;
442 import java.util.Locale;
443 import java.util.Map;
444 import java.util.Objects;
445 import java.util.Set;
446 import java.util.concurrent.CountDownLatch;
447 import java.util.concurrent.atomic.AtomicBoolean;
448 import java.util.concurrent.atomic.AtomicLong;
450 import dalvik.system.VMRuntime;
451 import libcore.io.IoUtils;
452 import libcore.util.EmptyArray;
454 public class ActivityManagerService extends IActivityManager.Stub
455 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
458 * Priority we boost main thread and RT of top app to.
460 public static final int TOP_APP_PRIORITY_BOOST = -10;
462 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
463 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
464 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
465 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
466 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
467 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
468 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
469 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
470 private static final String TAG_LRU = TAG + POSTFIX_LRU;
471 private static final String TAG_MU = TAG + POSTFIX_MU;
472 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
473 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
474 private static final String TAG_POWER = TAG + POSTFIX_POWER;
475 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
476 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
477 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
478 private static final String TAG_PSS = TAG + POSTFIX_PSS;
479 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
480 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
481 private static final String TAG_STACK = TAG + POSTFIX_STACK;
482 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
483 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
484 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
485 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
487 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
488 // here so that while the job scheduler can depend on AMS, the other way around
489 // need not be the case.
490 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
492 /** Control over CPU and battery monitoring */
493 // write battery stats every 30 minutes.
494 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
495 static final boolean MONITOR_CPU_USAGE = true;
496 // don't sample cpu less than every 5 seconds.
497 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
498 // wait possibly forever for next cpu sample.
499 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
500 static final boolean MONITOR_THREAD_CPU_USAGE = false;
502 // The flags that are set for all calls we make to the package manager.
503 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
505 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
507 // Amount of time after a call to stopAppSwitches() during which we will
508 // prevent further untrusted switches from happening.
509 static final long APP_SWITCH_DELAY_TIME = 5*1000;
511 // How long we wait for a launched process to attach to the activity manager
512 // before we decide it's never going to come up for real.
513 static final int PROC_START_TIMEOUT = 10*1000;
514 // How long we wait for an attached process to publish its content providers
515 // before we decide it must be hung.
516 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
518 // How long we wait for a launched process to attach to the activity manager
519 // before we decide it's never going to come up for real, when the process was
520 // started with a wrapper for instrumentation (such as Valgrind) because it
521 // could take much longer than usual.
522 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
524 // How long we allow a receiver to run before giving up on it.
525 static final int BROADCAST_FG_TIMEOUT = 10*1000;
526 static final int BROADCAST_BG_TIMEOUT = 60*1000;
528 // How long we wait until we timeout on key dispatching.
529 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
531 // How long we wait until we timeout on key dispatching during instrumentation.
532 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
534 // How long to wait in getAssistContextExtras for the activity and foreground services
535 // to respond with the result.
536 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
538 // How long top wait when going through the modern assist (which doesn't need to block
539 // on getting this result before starting to launch its UI).
540 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
542 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
543 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
545 // Maximum number of persisted Uri grants a package is allowed
546 static final int MAX_PERSISTED_URI_GRANTS = 128;
548 static final int MY_PID = myPid();
550 static final String[] EMPTY_STRING_ARRAY = new String[0];
552 // How many bytes to write into the dropbox log before truncating
553 static final int DROPBOX_MAX_SIZE = 192 * 1024;
554 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
555 // as one line, but close enough for now.
556 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
558 // Access modes for handleIncomingUser.
559 static final int ALLOW_NON_FULL = 0;
560 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
561 static final int ALLOW_FULL_ONLY = 2;
563 // Necessary ApplicationInfo flags to mark an app as persistent
564 private static final int PERSISTENT_MASK =
565 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
567 // Intent sent when remote bugreport collection has been completed
568 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
569 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
571 // Used to indicate that an app transition should be animated.
572 static final boolean ANIMATE = true;
574 // Determines whether to take full screen screenshots
575 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
578 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
580 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
583 * State indicating that there is no need for any blocking for network.
586 static final int NETWORK_STATE_NO_CHANGE = 0;
589 * State indicating that the main thread needs to be informed about the network wait.
592 static final int NETWORK_STATE_BLOCK = 1;
595 * State indicating that any threads waiting for network state to get updated can be unblocked.
598 static final int NETWORK_STATE_UNBLOCK = 2;
600 // Max character limit for a notification title. If the notification title is larger than this
601 // the notification will not be legible to the user.
602 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
604 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
606 /** All system services */
607 SystemServiceManager mSystemServiceManager;
608 AssistUtils mAssistUtils;
610 private Installer mInstaller;
612 /** Run all ActivityStacks through this */
613 final ActivityStackSupervisor mStackSupervisor;
614 private final KeyguardController mKeyguardController;
616 final ActivityStarter mActivityStarter;
618 final TaskChangeNotificationController mTaskChangeNotificationController;
620 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
622 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
624 public final IntentFirewall mIntentFirewall;
626 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
627 // default action automatically. Important for devices without direct input
629 private boolean mShowDialogs = true;
631 private final VrController mVrController;
633 // VR Vr2d Display Id.
634 int mVr2dDisplayId = INVALID_DISPLAY;
636 // Whether we should use SCHED_FIFO for UI and RenderThreads.
637 private boolean mUseFifoUiScheduling = false;
639 BroadcastQueue mFgBroadcastQueue;
640 BroadcastQueue mBgBroadcastQueue;
641 // Convenient for easy iteration over the queues. Foreground is first
642 // so that dispatch of foreground broadcasts gets precedence.
643 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
645 BroadcastStats mLastBroadcastStats;
646 BroadcastStats mCurBroadcastStats;
648 BroadcastQueue broadcastQueueForIntent(Intent intent) {
649 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
650 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
651 "Broadcast intent " + intent + " on "
652 + (isFg ? "foreground" : "background") + " queue");
653 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
657 * The last resumed activity. This is identical to the current resumed activity most
658 * of the time but could be different when we're pausing one activity before we resume
661 private ActivityRecord mLastResumedActivity;
664 * If non-null, we are tracking the time the user spends in the currently focused app.
666 private AppTimeTracker mCurAppTimeTracker;
669 * List of intents that were used to start the most recent tasks.
671 final RecentTasks mRecentTasks;
674 * For addAppTask: cached of the last activity component that was added.
676 ComponentName mLastAddedTaskComponent;
679 * For addAppTask: cached of the last activity uid that was added.
681 int mLastAddedTaskUid;
684 * For addAppTask: cached of the last ActivityInfo that was added.
686 ActivityInfo mLastAddedTaskActivity;
689 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
691 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
694 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
696 String mDeviceOwnerName;
698 final UserController mUserController;
700 final AppErrors mAppErrors;
703 * Dump of the activity state at the time of the last ANR. Cleared after
704 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
706 String mLastANRState;
709 * Indicates the maximum time spent waiting for the network rules to get updated.
712 long mWaitForNetworkTimeoutMs;
714 public boolean canShowErrorDialogs() {
715 return mShowDialogs && !mSleeping && !mShuttingDown
716 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
717 && !(UserManager.isDeviceInDemoMode(mContext)
718 && mUserController.getCurrentUser().isDemo());
721 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
722 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
724 static void boostPriorityForLockedSection() {
725 sThreadPriorityBooster.boost();
728 static void resetPriorityAfterLockedSection() {
729 sThreadPriorityBooster.reset();
732 public class PendingAssistExtras extends Binder implements Runnable {
733 public final ActivityRecord activity;
734 public boolean isHome;
735 public final Bundle extras;
736 public final Intent intent;
737 public final String hint;
738 public final IResultReceiver receiver;
739 public final int userHandle;
740 public boolean haveResult = false;
741 public Bundle result = null;
742 public AssistStructure structure = null;
743 public AssistContent content = null;
744 public Bundle receiverExtras;
746 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
747 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
748 activity = _activity;
752 receiver = _receiver;
753 receiverExtras = _receiverExtras;
754 userHandle = _userHandle;
759 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
760 synchronized (this) {
764 pendingAssistExtrasTimedOut(this);
768 final ArrayList<PendingAssistExtras> mPendingAssistExtras
769 = new ArrayList<PendingAssistExtras>();
772 * Process management.
774 final ProcessList mProcessList = new ProcessList();
777 * All of the applications we currently have running organized by name.
778 * The keys are strings of the application package name (as
779 * returned by the package manager), and the keys are ApplicationRecord
782 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
785 * Tracking long-term execution of processes to look for abuse and other
788 final ProcessStatsService mProcessStats;
791 * The currently running isolated processes.
793 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
796 * Counter for assigning isolated process uids, to avoid frequently reusing the
799 int mNextIsolatedProcessUid = 0;
802 * The currently running heavy-weight process, if any.
804 ProcessRecord mHeavyWeightProcess = null;
807 * Non-persistent appId whitelist for background restrictions
809 int[] mBackgroundAppIdWhitelist = new int[] {
814 * Broadcast actions that will always be deliverable to unlaunched/background apps
816 ArraySet<String> mBackgroundLaunchBroadcasts;
819 * All of the processes we currently have running organized by pid.
820 * The keys are the pid running the application.
822 * <p>NOTE: This object is protected by its own lock, NOT the global
823 * activity manager lock!
825 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
828 * All of the processes that have been forced to be important. The key
829 * is the pid of the caller who requested it (we hold a death
832 abstract class ImportanceToken implements IBinder.DeathRecipient {
837 ImportanceToken(int _pid, IBinder _token, String _reason) {
844 public String toString() {
845 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
846 + " " + reason + " " + pid + " " + token + " }";
849 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
852 * List of records for processes that someone had tried to start before the
853 * system was ready. We don't start them at that point, but ensure they
854 * are started by the time booting is complete.
856 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
859 * List of persistent applications that are in the process
862 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
865 * Processes that are being forcibly torn down.
867 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
870 * List of running applications, sorted by recent usage.
871 * The first entry in the list is the least recently used.
873 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
876 * Where in mLruProcesses that the processes hosting activities start.
878 int mLruProcessActivityStart = 0;
881 * Where in mLruProcesses that the processes hosting services start.
882 * This is after (lower index) than mLruProcessesActivityStart.
884 int mLruProcessServiceStart = 0;
887 * List of processes that should gc as soon as things are idle.
889 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
892 * Processes we want to collect PSS data from.
894 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
896 private boolean mBinderTransactionTrackingEnabled = false;
899 * Last time we requested PSS data of all processes.
901 long mLastFullPssTime = SystemClock.uptimeMillis();
904 * If set, the next time we collect PSS data we should do a full collection
905 * with data from native processes and the kernel.
907 boolean mFullPssPending = false;
910 * This is the process holding what we currently consider to be
911 * the "home" activity.
913 ProcessRecord mHomeProcess;
916 * This is the process holding the activity the user last visited that
917 * is in a different process from the one they are currently in.
919 ProcessRecord mPreviousProcess;
922 * The time at which the previous process was last visible.
924 long mPreviousProcessVisibleTime;
927 * Track all uids that have actively running processes.
929 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
932 * This is for verifying the UID report flow.
934 static final boolean VALIDATE_UID_STATES = true;
935 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
938 * Packages that the user has asked to have run in screen size
939 * compatibility mode instead of filling the screen.
941 final CompatModePackages mCompatModePackages;
944 * Set of IntentSenderRecord objects that are currently active.
946 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
947 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
950 * Fingerprints (hashCode()) of stack traces that we've
951 * already logged DropBox entries for. Guarded by itself. If
952 * something (rogue user app) forces this over
953 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
955 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
956 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
959 * Strict Mode background batched logging state.
961 * The string buffer is guarded by itself, and its lock is also
962 * used to determine if another batched write is already
965 private final StringBuilder mStrictModeBuffer = new StringBuilder();
968 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
969 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
971 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
974 * Resolver for broadcast intents to registered receivers.
975 * Holds BroadcastFilter (subclass of IntentFilter).
977 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
978 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
980 protected boolean allowFilterResult(
981 BroadcastFilter filter, List<BroadcastFilter> dest) {
982 IBinder target = filter.receiverList.receiver.asBinder();
983 for (int i = dest.size() - 1; i >= 0; i--) {
984 if (dest.get(i).receiverList.receiver.asBinder() == target) {
992 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
993 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
994 || userId == filter.owningUserId) {
995 return super.newResult(filter, match, userId);
1001 protected BroadcastFilter[] newArray(int size) {
1002 return new BroadcastFilter[size];
1006 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1007 return packageName.equals(filter.packageName);
1012 * State of all active sticky broadcasts per user. Keys are the action of the
1013 * sticky Intent, values are an ArrayList of all broadcasted intents with
1014 * that action (which should usually be one). The SparseArray is keyed
1015 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1016 * for stickies that are sent to all users.
1018 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1019 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1021 final ActiveServices mServices;
1023 final static class Association {
1024 final int mSourceUid;
1025 final String mSourceProcess;
1026 final int mTargetUid;
1027 final ComponentName mTargetComponent;
1028 final String mTargetProcess;
1036 // states of the source process when the bind occurred.
1037 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1038 long mLastStateUptime;
1039 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1040 - ActivityManager.MIN_PROCESS_STATE+1];
1042 Association(int sourceUid, String sourceProcess, int targetUid,
1043 ComponentName targetComponent, String targetProcess) {
1044 mSourceUid = sourceUid;
1045 mSourceProcess = sourceProcess;
1046 mTargetUid = targetUid;
1047 mTargetComponent = targetComponent;
1048 mTargetProcess = targetProcess;
1053 * When service association tracking is enabled, this is all of the associations we
1054 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1055 * -> association data.
1057 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1058 mAssociations = new SparseArray<>();
1059 boolean mTrackingAssociations;
1062 * Backup/restore process management
1064 String mBackupAppName = null;
1065 BackupRecord mBackupTarget = null;
1067 final ProviderMap mProviderMap;
1070 * List of content providers who have clients waiting for them. The
1071 * application is currently being launched and the provider will be
1072 * removed from this list once it is published.
1074 final ArrayList<ContentProviderRecord> mLaunchingProviders
1075 = new ArrayList<ContentProviderRecord>();
1078 * File storing persisted {@link #mGrantedUriPermissions}.
1080 private final AtomicFile mGrantFile;
1082 /** XML constants used in {@link #mGrantFile} */
1083 private static final String TAG_URI_GRANTS = "uri-grants";
1084 private static final String TAG_URI_GRANT = "uri-grant";
1085 private static final String ATTR_USER_HANDLE = "userHandle";
1086 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1087 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1088 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1089 private static final String ATTR_TARGET_PKG = "targetPkg";
1090 private static final String ATTR_URI = "uri";
1091 private static final String ATTR_MODE_FLAGS = "modeFlags";
1092 private static final String ATTR_CREATED_TIME = "createdTime";
1093 private static final String ATTR_PREFIX = "prefix";
1096 * Global set of specific {@link Uri} permissions that have been granted.
1097 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1098 * to {@link UriPermission#uri} to {@link UriPermission}.
1101 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1102 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1104 public static class GrantUri {
1105 public final int sourceUserId;
1106 public final Uri uri;
1107 public boolean prefix;
1109 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1110 this.sourceUserId = sourceUserId;
1112 this.prefix = prefix;
1116 public int hashCode() {
1118 hashCode = 31 * hashCode + sourceUserId;
1119 hashCode = 31 * hashCode + uri.hashCode();
1120 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1125 public boolean equals(Object o) {
1126 if (o instanceof GrantUri) {
1127 GrantUri other = (GrantUri) o;
1128 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1129 && prefix == other.prefix;
1135 public String toString() {
1136 String result = uri.toString() + " [user " + sourceUserId + "]";
1137 if (prefix) result += " [prefix]";
1141 public String toSafeString() {
1142 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1143 if (prefix) result += " [prefix]";
1147 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1148 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1149 ContentProvider.getUriWithoutUserId(uri), false);
1153 CoreSettingsObserver mCoreSettingsObserver;
1155 FontScaleSettingObserver mFontScaleSettingObserver;
1157 private final class FontScaleSettingObserver extends ContentObserver {
1158 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1160 public FontScaleSettingObserver() {
1162 ContentResolver resolver = mContext.getContentResolver();
1163 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1167 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1168 if (mFontScaleUri.equals(uri)) {
1169 updateFontScaleIfNeeded(userId);
1175 * Thread-local storage used to carry caller permissions over through
1176 * indirect content-provider access.
1178 private class Identity {
1179 public final IBinder token;
1180 public final int pid;
1181 public final int uid;
1183 Identity(IBinder _token, int _pid, int _uid) {
1190 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1193 * All information we have collected about the runtime performance of
1194 * any user id that can impact battery performance.
1196 final BatteryStatsService mBatteryStatsService;
1199 * Information about component usage
1201 UsageStatsManagerInternal mUsageStatsService;
1204 * Access to DeviceIdleController service.
1206 DeviceIdleController.LocalService mLocalDeviceIdleController;
1209 * Set of app ids that are whitelisted for device idle and thus background check.
1211 int[] mDeviceIdleWhitelist = new int[0];
1214 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1216 int[] mDeviceIdleTempWhitelist = new int[0];
1218 static final class PendingTempWhitelist {
1219 final int targetUid;
1220 final long duration;
1223 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1224 targetUid = _targetUid;
1225 duration = _duration;
1230 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1233 * Information about and control over application operations
1235 final AppOpsService mAppOpsService;
1237 /** Current sequencing integer of the configuration, for skipping old configurations. */
1238 private int mConfigurationSeq;
1241 * Temp object used when global and/or display override configuration is updated. It is also
1242 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1245 private Configuration mTempConfig = new Configuration();
1247 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1248 new UpdateConfigurationResult();
1249 private static final class UpdateConfigurationResult {
1250 // Configuration changes that were updated.
1252 // If the activity was relaunched to match the new configuration.
1253 boolean activityRelaunched;
1257 activityRelaunched = false;
1261 boolean mSuppressResizeConfigChanges;
1264 * Hardware-reported OpenGLES version.
1266 final int GL_ES_VERSION;
1269 * List of initialization arguments to pass to all processes when binding applications to them.
1270 * For example, references to the commonly used services.
1272 HashMap<String, IBinder> mAppBindArgs;
1273 HashMap<String, IBinder> mIsolatedAppBindArgs;
1276 * Temporary to avoid allocations. Protected by main lock.
1278 final StringBuilder mStringBuilder = new StringBuilder(256);
1281 * Used to control how we initialize the service.
1283 ComponentName mTopComponent;
1284 String mTopAction = Intent.ACTION_MAIN;
1287 volatile boolean mProcessesReady = false;
1288 volatile boolean mSystemReady = false;
1289 volatile boolean mOnBattery = false;
1290 volatile int mFactoryTest;
1292 @GuardedBy("this") boolean mBooting = false;
1293 @GuardedBy("this") boolean mCallFinishBooting = false;
1294 @GuardedBy("this") boolean mBootAnimationComplete = false;
1295 @GuardedBy("this") boolean mLaunchWarningShown = false;
1296 @GuardedBy("this") boolean mCheckedForSetup = false;
1298 final Context mContext;
1301 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1302 * change at runtime. Use mContext for non-UI purposes.
1304 final Context mUiContext;
1307 * The time at which we will allow normal application switches again,
1308 * after a call to {@link #stopAppSwitches()}.
1310 long mAppSwitchesAllowedTime;
1313 * This is set to true after the first switch after mAppSwitchesAllowedTime
1314 * is set; any switches after that will clear the time.
1316 boolean mDidAppSwitch;
1319 * Last time (in uptime) at which we checked for power usage.
1321 long mLastPowerCheckUptime;
1324 * Set while we are wanting to sleep, to prevent any
1325 * activities from being started/resumed.
1327 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1329 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1330 * while in the sleep state until there is a pending transition out of sleep, in which case
1331 * mSleeping is set to false, and remains false while awake.
1333 * Whether mSleeping can quickly toggled between true/false without the device actually
1334 * display changing states is undefined.
1336 private boolean mSleeping = false;
1339 * The process state used for processes that are running the top activities.
1340 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1342 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1345 * Set while we are running a voice interaction. This overrides
1346 * sleeping while it is active.
1348 IVoiceInteractionSession mRunningVoice;
1351 * For some direct access we need to power manager.
1353 PowerManagerInternal mLocalPowerManager;
1356 * We want to hold a wake lock while running a voice interaction session, since
1357 * this may happen with the screen off and we need to keep the CPU running to
1358 * be able to continue to interact with the user.
1360 PowerManager.WakeLock mVoiceWakeLock;
1363 * State of external calls telling us if the device is awake or asleep.
1365 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1368 * Set if we are shutting down the system, similar to sleeping.
1370 boolean mShuttingDown = false;
1373 * Current sequence id for oom_adj computation traversal.
1378 * Current sequence id for process LRU updating.
1383 * Keep track of the non-cached/empty process we last found, to help
1384 * determine how to distribute cached/empty processes next time.
1386 int mNumNonCachedProcs = 0;
1389 * Keep track of the number of cached hidden procs, to balance oom adj
1390 * distribution between those and empty procs.
1392 int mNumCachedHiddenProcs = 0;
1395 * Keep track of the number of service processes we last found, to
1396 * determine on the next iteration which should be B services.
1398 int mNumServiceProcs = 0;
1399 int mNewNumAServiceProcs = 0;
1400 int mNewNumServiceProcs = 0;
1403 * Allow the current computed overall memory level of the system to go down?
1404 * This is set to false when we are killing processes for reasons other than
1405 * memory management, so that the now smaller process list will not be taken as
1406 * an indication that memory is tighter.
1408 boolean mAllowLowerMemLevel = false;
1411 * The last computed memory level, for holding when we are in a state that
1412 * processes are going away for other reasons.
1414 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1417 * The last total number of process we have, to determine if changes actually look
1418 * like a shrinking number of process due to lower RAM.
1420 int mLastNumProcesses;
1423 * The uptime of the last time we performed idle maintenance.
1425 long mLastIdleTime = SystemClock.uptimeMillis();
1428 * Total time spent with RAM that has been added in the past since the last idle time.
1430 long mLowRamTimeSinceLastIdle = 0;
1433 * If RAM is currently low, when that horrible situation started.
1435 long mLowRamStartTime = 0;
1438 * For reporting to battery stats the current top application.
1440 private String mCurResumedPackage = null;
1441 private int mCurResumedUid = -1;
1444 * For reporting to battery stats the apps currently running foreground
1445 * service. The ProcessMap is package/uid tuples; each of these contain
1446 * an array of the currently foreground processes.
1448 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1449 = new ProcessMap<ArrayList<ProcessRecord>>();
1452 * Set if the systemServer made a call to enterSafeMode.
1457 * If true, we are running under a test environment so will sample PSS from processes
1458 * much more rapidly to try to collect better data when the tests are rapidly
1459 * running through apps.
1461 boolean mTestPssMode = false;
1463 String mDebugApp = null;
1464 boolean mWaitForDebugger = false;
1465 boolean mDebugTransient = false;
1466 String mOrigDebugApp = null;
1467 boolean mOrigWaitForDebugger = false;
1468 boolean mAlwaysFinishActivities = false;
1469 boolean mForceResizableActivities;
1471 * Flag that indicates if multi-window is enabled.
1473 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1474 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1475 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1476 * At least one of the forms of multi-window must be enabled in order for this flag to be
1477 * initialized to 'true'.
1479 * @see #mSupportsSplitScreenMultiWindow
1480 * @see #mSupportsFreeformWindowManagement
1481 * @see #mSupportsPictureInPicture
1482 * @see #mSupportsMultiDisplay
1484 boolean mSupportsMultiWindow;
1485 boolean mSupportsSplitScreenMultiWindow;
1486 boolean mSupportsFreeformWindowManagement;
1487 boolean mSupportsPictureInPicture;
1488 boolean mSupportsMultiDisplay;
1489 boolean mSupportsLeanbackOnly;
1490 IActivityController mController = null;
1491 boolean mControllerIsAMonkey = false;
1492 String mProfileApp = null;
1493 ProcessRecord mProfileProc = null;
1494 ProfilerInfo mProfilerInfo = null;
1495 int mProfileType = 0;
1496 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1497 String mMemWatchDumpProcName;
1498 String mMemWatchDumpFile;
1499 int mMemWatchDumpPid;
1500 int mMemWatchDumpUid;
1501 String mTrackAllocationApp = null;
1502 String mNativeDebuggingApp = null;
1504 final long[] mTmpLong = new long[2];
1506 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1509 * A global counter for generating sequence numbers.
1510 * This value will be used when incrementing sequence numbers in individual uidRecords.
1512 * Having a global counter ensures that seq numbers are monotonically increasing for a
1513 * particular uid even when the uidRecord is re-created.
1517 long mProcStateSeqCounter = 0;
1519 private final Injector mInjector;
1521 static final class ProcessChangeItem {
1522 static final int CHANGE_ACTIVITIES = 1<<0;
1527 boolean foregroundActivities;
1530 static final class UidObserverRegistration {
1536 final SparseIntArray lastProcStates;
1538 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1542 cutpoint = _cutpoint;
1543 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1544 lastProcStates = new SparseIntArray();
1546 lastProcStates = null;
1551 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1552 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1554 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1555 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1557 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1558 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1560 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1561 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1563 OomAdjObserver mCurOomAdjObserver;
1566 interface OomAdjObserver {
1567 void onOomAdjMessage(String msg);
1571 * Runtime CPU use collection thread. This object's lock is used to
1572 * perform synchronization with the thread (notifying it to run).
1574 final Thread mProcessCpuThread;
1577 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1578 * Must acquire this object's lock when accessing it.
1579 * NOTE: this lock will be held while doing long operations (trawling
1580 * through all processes in /proc), so it should never be acquired by
1581 * any critical paths such as when holding the main activity manager lock.
1583 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1584 MONITOR_THREAD_CPU_USAGE);
1585 final AtomicLong mLastCpuTime = new AtomicLong(0);
1586 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1587 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1589 long mLastWriteTime = 0;
1592 * Used to retain an update lock when the foreground activity is in
1595 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1598 * Set to true after the system has finished booting.
1600 boolean mBooted = false;
1602 WindowManagerService mWindowManager;
1603 final ActivityThread mSystemThread;
1605 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1606 final ProcessRecord mApp;
1608 final IApplicationThread mAppThread;
1610 AppDeathRecipient(ProcessRecord app, int pid,
1611 IApplicationThread thread) {
1612 if (DEBUG_ALL) Slog.v(
1613 TAG, "New death recipient " + this
1614 + " for thread " + thread.asBinder());
1617 mAppThread = thread;
1621 public void binderDied() {
1622 if (DEBUG_ALL) Slog.v(
1623 TAG, "Death received in " + this
1624 + " for thread " + mAppThread.asBinder());
1625 synchronized(ActivityManagerService.this) {
1626 appDiedLocked(mApp, mPid, mAppThread, true);
1631 static final int SHOW_ERROR_UI_MSG = 1;
1632 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1633 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1634 static final int UPDATE_CONFIGURATION_MSG = 4;
1635 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1636 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1637 static final int SERVICE_TIMEOUT_MSG = 12;
1638 static final int UPDATE_TIME_ZONE = 13;
1639 static final int SHOW_UID_ERROR_UI_MSG = 14;
1640 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1641 static final int PROC_START_TIMEOUT_MSG = 20;
1642 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1643 static final int KILL_APPLICATION_MSG = 22;
1644 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1645 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1646 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1647 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1648 static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1649 static final int CLEAR_DNS_CACHE_MSG = 28;
1650 static final int UPDATE_HTTP_PROXY_MSG = 29;
1651 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1652 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1653 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1654 static final int REPORT_MEM_USAGE_MSG = 33;
1655 static final int REPORT_USER_SWITCH_MSG = 34;
1656 static final int CONTINUE_USER_SWITCH_MSG = 35;
1657 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1658 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1659 static final int PERSIST_URI_GRANTS_MSG = 38;
1660 static final int REQUEST_ALL_PSS_MSG = 39;
1661 static final int START_PROFILES_MSG = 40;
1662 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1663 static final int SYSTEM_USER_START_MSG = 42;
1664 static final int SYSTEM_USER_CURRENT_MSG = 43;
1665 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1666 static final int FINISH_BOOTING_MSG = 45;
1667 static final int START_USER_SWITCH_UI_MSG = 46;
1668 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1669 static final int DISMISS_DIALOG_UI_MSG = 48;
1670 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1671 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1672 static final int DELETE_DUMPHEAP_MSG = 51;
1673 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1674 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1675 static final int REPORT_TIME_TRACKER_MSG = 54;
1676 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1677 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1678 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1679 static final int IDLE_UIDS_MSG = 58;
1680 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1681 static final int LOG_STACK_STATE = 60;
1682 static final int VR_MODE_CHANGE_MSG = 61;
1683 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1684 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1685 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1686 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1687 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1688 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1689 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1690 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1691 static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1692 static final int START_USER_SWITCH_FG_MSG = 712;
1693 static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1695 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1696 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1697 static final int FIRST_COMPAT_MODE_MSG = 300;
1698 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1700 static ServiceThread sKillThread = null;
1701 static KillHandler sKillHandler = null;
1703 CompatModeDialog mCompatModeDialog;
1704 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1705 long mLastMemUsageReportTime = 0;
1708 * Flag whether the current user is a "monkey", i.e. whether
1709 * the UI is driven by a UI automation tool.
1711 private boolean mUserIsMonkey;
1713 /** Flag whether the device has a Recents UI */
1714 boolean mHasRecents;
1716 /** The dimensions of the thumbnails in the Recents UI. */
1717 int mThumbnailWidth;
1718 int mThumbnailHeight;
1719 float mFullscreenThumbnailScale;
1721 final ServiceThread mHandlerThread;
1722 final MainHandler mHandler;
1723 final Handler mUiHandler;
1725 final ActivityManagerConstants mConstants;
1727 PackageManagerInternal mPackageManagerInt;
1729 // VoiceInteraction session ID that changes for each new request except when
1730 // being called for multiwindow assist in a single session.
1731 private int mViSessionId = 1000;
1733 final boolean mPermissionReviewRequired;
1735 private static String sTheRealBuildSerial = Build.UNKNOWN;
1738 * Current global configuration information. Contains general settings for the entire system,
1739 * also corresponds to the merged configuration of the default display.
1741 Configuration getGlobalConfiguration() {
1742 return mStackSupervisor.getConfiguration();
1745 final class KillHandler extends Handler {
1746 static final int KILL_PROCESS_GROUP_MSG = 4000;
1748 public KillHandler(Looper looper) {
1749 super(looper, null, true);
1753 public void handleMessage(Message msg) {
1755 case KILL_PROCESS_GROUP_MSG:
1757 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1758 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1759 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1764 super.handleMessage(msg);
1769 final class UiHandler extends Handler {
1770 public UiHandler() {
1771 super(com.android.server.UiThread.get().getLooper(), null, true);
1775 public void handleMessage(Message msg) {
1777 case SHOW_ERROR_UI_MSG: {
1778 mAppErrors.handleShowAppErrorUi(msg);
1779 ensureBootCompleted();
1781 case SHOW_NOT_RESPONDING_UI_MSG: {
1782 mAppErrors.handleShowAnrUi(msg);
1783 ensureBootCompleted();
1785 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1786 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1787 synchronized (ActivityManagerService.this) {
1788 ProcessRecord proc = (ProcessRecord) data.get("app");
1790 Slog.e(TAG, "App not found when showing strict mode dialog.");
1793 if (proc.crashDialog != null) {
1794 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1797 AppErrorResult res = (AppErrorResult) data.get("result");
1798 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1799 Dialog d = new StrictModeViolationDialog(mUiContext,
1800 ActivityManagerService.this, res, proc);
1802 proc.crashDialog = d;
1804 // The device is asleep, so just pretend that the user
1805 // saw a crash dialog and hit "force quit".
1809 ensureBootCompleted();
1811 case SHOW_FACTORY_ERROR_UI_MSG: {
1812 Dialog d = new FactoryErrorDialog(
1813 mUiContext, msg.getData().getCharSequence("msg"));
1815 ensureBootCompleted();
1817 case WAIT_FOR_DEBUGGER_UI_MSG: {
1818 synchronized (ActivityManagerService.this) {
1819 ProcessRecord app = (ProcessRecord)msg.obj;
1820 if (msg.arg1 != 0) {
1821 if (!app.waitedForDebugger) {
1822 Dialog d = new AppWaitingForDebuggerDialog(
1823 ActivityManagerService.this,
1826 app.waitedForDebugger = true;
1830 if (app.waitDialog != null) {
1831 app.waitDialog.dismiss();
1832 app.waitDialog = null;
1837 case SHOW_UID_ERROR_UI_MSG: {
1839 AlertDialog d = new BaseErrorDialog(mUiContext);
1840 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1841 d.setCancelable(false);
1842 d.setTitle(mUiContext.getText(R.string.android_system_label));
1843 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1844 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1845 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1849 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1851 AlertDialog d = new BaseErrorDialog(mUiContext);
1852 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1853 d.setCancelable(false);
1854 d.setTitle(mUiContext.getText(R.string.android_system_label));
1855 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1856 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1857 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1861 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1862 synchronized (ActivityManagerService.this) {
1863 ActivityRecord ar = (ActivityRecord) msg.obj;
1864 if (mCompatModeDialog != null) {
1865 if (mCompatModeDialog.mAppInfo.packageName.equals(
1866 ar.info.applicationInfo.packageName)) {
1869 mCompatModeDialog.dismiss();
1870 mCompatModeDialog = null;
1872 if (ar != null && false) {
1873 if (mCompatModePackages.getPackageAskCompatModeLocked(
1875 int mode = mCompatModePackages.computeCompatModeLocked(
1876 ar.info.applicationInfo);
1877 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1878 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1879 mCompatModeDialog = new CompatModeDialog(
1880 ActivityManagerService.this, mUiContext,
1881 ar.info.applicationInfo);
1882 mCompatModeDialog.show();
1889 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1890 synchronized (ActivityManagerService.this) {
1891 final ActivityRecord ar = (ActivityRecord) msg.obj;
1892 if (mUnsupportedDisplaySizeDialog != null) {
1893 mUnsupportedDisplaySizeDialog.dismiss();
1894 mUnsupportedDisplaySizeDialog = null;
1896 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1898 // TODO(multi-display): Show dialog on appropriate display.
1899 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1900 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1901 mUnsupportedDisplaySizeDialog.show();
1906 case START_USER_SWITCH_UI_MSG: {
1907 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1910 case DISMISS_DIALOG_UI_MSG: {
1911 final Dialog d = (Dialog) msg.obj;
1915 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1916 dispatchProcessesChanged();
1919 case DISPATCH_PROCESS_DIED_UI_MSG: {
1920 final int pid = msg.arg1;
1921 final int uid = msg.arg2;
1922 dispatchProcessDied(pid, uid);
1925 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1926 dispatchUidsChanged();
1928 case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1929 dispatchOomAdjObserver((String)msg.obj);
1931 case PUSH_TEMP_WHITELIST_UI_MSG: {
1932 pushTempWhitelist();
1938 final class MainHandler extends Handler {
1939 public MainHandler(Looper looper) {
1940 super(looper, null, true);
1944 public void handleMessage(Message msg) {
1946 case UPDATE_CONFIGURATION_MSG: {
1947 final ContentResolver resolver = mContext.getContentResolver();
1948 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1951 case GC_BACKGROUND_PROCESSES_MSG: {
1952 synchronized (ActivityManagerService.this) {
1953 performAppGcsIfAppropriateLocked();
1956 case SERVICE_TIMEOUT_MSG: {
1957 mServices.serviceTimeout((ProcessRecord)msg.obj);
1959 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1960 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1962 case SERVICE_FOREGROUND_CRASH_MSG: {
1963 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1965 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1966 RemoteCallbackList<IResultReceiver> callbacks
1967 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1968 int N = callbacks.beginBroadcast();
1969 for (int i = 0; i < N; i++) {
1971 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1972 } catch (RemoteException e) {
1975 callbacks.finishBroadcast();
1977 case UPDATE_TIME_ZONE: {
1978 synchronized (ActivityManagerService.this) {
1979 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1980 ProcessRecord r = mLruProcesses.get(i);
1981 if (r.thread != null) {
1983 r.thread.updateTimeZone();
1984 } catch (RemoteException ex) {
1985 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1991 case CLEAR_DNS_CACHE_MSG: {
1992 synchronized (ActivityManagerService.this) {
1993 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1994 ProcessRecord r = mLruProcesses.get(i);
1995 if (r.thread != null) {
1997 r.thread.clearDnsCache();
1998 } catch (RemoteException ex) {
1999 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2005 case UPDATE_HTTP_PROXY_MSG: {
2006 ProxyInfo proxy = (ProxyInfo)msg.obj;
2009 String exclList = "";
2010 Uri pacFileUrl = Uri.EMPTY;
2011 if (proxy != null) {
2012 host = proxy.getHost();
2013 port = Integer.toString(proxy.getPort());
2014 exclList = proxy.getExclusionListAsString();
2015 pacFileUrl = proxy.getPacFileUrl();
2017 synchronized (ActivityManagerService.this) {
2018 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2019 ProcessRecord r = mLruProcesses.get(i);
2020 if (r.thread != null) {
2022 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2023 } catch (RemoteException ex) {
2024 Slog.w(TAG, "Failed to update http proxy for: " +
2025 r.info.processName);
2031 case PROC_START_TIMEOUT_MSG: {
2032 ProcessRecord app = (ProcessRecord)msg.obj;
2033 synchronized (ActivityManagerService.this) {
2034 processStartTimedOutLocked(app);
2037 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2038 ProcessRecord app = (ProcessRecord)msg.obj;
2039 synchronized (ActivityManagerService.this) {
2040 processContentProviderPublishTimedOutLocked(app);
2043 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2044 synchronized (ActivityManagerService.this) {
2045 mActivityStarter.doPendingActivityLaunchesLocked(true);
2048 case KILL_APPLICATION_MSG: {
2049 synchronized (ActivityManagerService.this) {
2050 final int appId = msg.arg1;
2051 final int userId = msg.arg2;
2052 Bundle bundle = (Bundle)msg.obj;
2053 String pkg = bundle.getString("pkg");
2054 String reason = bundle.getString("reason");
2055 forceStopPackageLocked(pkg, appId, false, false, true, false,
2056 false, userId, reason);
2059 case FINALIZE_PENDING_INTENT_MSG: {
2060 ((PendingIntentRecord)msg.obj).completeFinalize();
2062 case POST_HEAVY_NOTIFICATION_MSG: {
2063 INotificationManager inm = NotificationManager.getService();
2068 ActivityRecord root = (ActivityRecord)msg.obj;
2069 ProcessRecord process = root.app;
2070 if (process == null) {
2075 Context context = mContext.createPackageContext(process.info.packageName, 0);
2076 String text = mContext.getString(R.string.heavy_weight_notification,
2077 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2078 Notification notification =
2079 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2080 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2084 .setColor(mContext.getColor(
2085 com.android.internal.R.color.system_notification_accent_color))
2086 .setContentTitle(text)
2088 mContext.getText(R.string.heavy_weight_notification_detail))
2089 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2090 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2091 new UserHandle(root.userId)))
2094 inm.enqueueNotificationWithTag("android", "android", null,
2095 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2096 notification, root.userId);
2097 } catch (RuntimeException e) {
2098 Slog.w(ActivityManagerService.TAG,
2099 "Error showing notification for heavy-weight app", e);
2100 } catch (RemoteException e) {
2102 } catch (NameNotFoundException e) {
2103 Slog.w(TAG, "Unable to create context for heavy notification", e);
2106 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2107 INotificationManager inm = NotificationManager.getService();
2112 inm.cancelNotificationWithTag("android", null,
2113 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2114 } catch (RuntimeException e) {
2115 Slog.w(ActivityManagerService.TAG,
2116 "Error canceling notification for service", e);
2117 } catch (RemoteException e) {
2120 case CHECK_EXCESSIVE_POWER_USE_MSG: {
2121 synchronized (ActivityManagerService.this) {
2122 checkExcessivePowerUsageLocked();
2123 removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2124 Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2125 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2128 case REPORT_MEM_USAGE_MSG: {
2129 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2130 Thread thread = new Thread() {
2131 @Override public void run() {
2132 reportMemUsage(memInfos);
2138 case START_USER_SWITCH_FG_MSG: {
2139 mUserController.startUserInForeground(msg.arg1);
2142 case REPORT_USER_SWITCH_MSG: {
2143 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2146 case CONTINUE_USER_SWITCH_MSG: {
2147 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2150 case USER_SWITCH_TIMEOUT_MSG: {
2151 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2154 case IMMERSIVE_MODE_LOCK_MSG: {
2155 final boolean nextState = (msg.arg1 != 0);
2156 if (mUpdateLock.isHeld() != nextState) {
2157 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2158 "Applying new update lock state '" + nextState
2159 + "' for " + (ActivityRecord)msg.obj);
2161 mUpdateLock.acquire();
2163 mUpdateLock.release();
2168 case PERSIST_URI_GRANTS_MSG: {
2169 writeGrantedUriPermissions();
2172 case REQUEST_ALL_PSS_MSG: {
2173 synchronized (ActivityManagerService.this) {
2174 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2178 case START_PROFILES_MSG: {
2179 synchronized (ActivityManagerService.this) {
2180 mUserController.startProfilesLocked();
2184 case UPDATE_TIME_PREFERENCE_MSG: {
2185 // The user's time format preference might have changed.
2186 // For convenience we re-use the Intent extra values.
2187 synchronized (ActivityManagerService.this) {
2188 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2189 ProcessRecord r = mLruProcesses.get(i);
2190 if (r.thread != null) {
2192 r.thread.updateTimePrefs(msg.arg1);
2193 } catch (RemoteException ex) {
2194 Slog.w(TAG, "Failed to update preferences for: "
2195 + r.info.processName);
2202 case SYSTEM_USER_START_MSG: {
2203 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2204 Integer.toString(msg.arg1), msg.arg1);
2205 mSystemServiceManager.startUser(msg.arg1);
2208 case SYSTEM_USER_UNLOCK_MSG: {
2209 final int userId = msg.arg1;
2210 mSystemServiceManager.unlockUser(userId);
2211 synchronized (ActivityManagerService.this) {
2212 mRecentTasks.loadUserRecentsLocked(userId);
2214 if (userId == UserHandle.USER_SYSTEM) {
2215 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2217 installEncryptionUnawareProviders(userId);
2218 mUserController.finishUserUnlocked((UserState) msg.obj);
2221 case SYSTEM_USER_CURRENT_MSG: {
2222 mBatteryStatsService.noteEvent(
2223 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2224 Integer.toString(msg.arg2), msg.arg2);
2225 mBatteryStatsService.noteEvent(
2226 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2227 Integer.toString(msg.arg1), msg.arg1);
2228 mSystemServiceManager.switchUser(msg.arg1);
2231 case ENTER_ANIMATION_COMPLETE_MSG: {
2232 synchronized (ActivityManagerService.this) {
2233 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2234 if (r != null && r.app != null && r.app.thread != null) {
2236 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2237 } catch (RemoteException e) {
2243 case FINISH_BOOTING_MSG: {
2244 if (msg.arg1 != 0) {
2245 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2247 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2249 if (msg.arg2 != 0) {
2250 enableScreenAfterBoot();
2254 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2256 Locale l = (Locale) msg.obj;
2257 IBinder service = ServiceManager.getService("mount");
2258 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2259 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2260 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2261 } catch (RemoteException e) {
2262 Log.e(TAG, "Error storing locale for decryption UI", e);
2266 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2267 final int uid = msg.arg1;
2268 final byte[] firstPacket = (byte[]) msg.obj;
2270 synchronized (mPidsSelfLocked) {
2271 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2272 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2275 p.thread.notifyCleartextNetwork(firstPacket);
2276 } catch (RemoteException ignored) {
2283 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2284 final String procName;
2286 final long memLimit;
2287 final String reportPackage;
2288 synchronized (ActivityManagerService.this) {
2289 procName = mMemWatchDumpProcName;
2290 uid = mMemWatchDumpUid;
2291 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2293 val = mMemWatchProcesses.get(procName, 0);
2296 memLimit = val.first;
2297 reportPackage = val.second;
2300 reportPackage = null;
2303 if (procName == null) {
2307 if (DEBUG_PSS) Slog.d(TAG_PSS,
2308 "Showing dump heap notification from " + procName + "/" + uid);
2310 INotificationManager inm = NotificationManager.getService();
2315 String text = mContext.getString(R.string.dump_heap_notification, procName);
2318 Intent deleteIntent = new Intent();
2319 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2320 Intent intent = new Intent();
2321 intent.setClassName("android", DumpHeapActivity.class.getName());
2322 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2323 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2324 if (reportPackage != null) {
2325 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2327 int userId = UserHandle.getUserId(uid);
2328 Notification notification =
2329 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2330 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2333 .setAutoCancel(true)
2335 .setColor(mContext.getColor(
2336 com.android.internal.R.color.system_notification_accent_color))
2337 .setContentTitle(text)
2339 mContext.getText(R.string.dump_heap_notification_detail))
2340 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2341 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2342 new UserHandle(userId)))
2343 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2344 deleteIntent, 0, UserHandle.SYSTEM))
2348 inm.enqueueNotificationWithTag("android", "android", null,
2349 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2350 notification, userId);
2351 } catch (RuntimeException e) {
2352 Slog.w(ActivityManagerService.TAG,
2353 "Error showing notification for dump heap", e);
2354 } catch (RemoteException e) {
2357 case DELETE_DUMPHEAP_MSG: {
2358 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2359 null, DumpHeapActivity.JAVA_URI,
2360 Intent.FLAG_GRANT_READ_URI_PERMISSION
2361 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2362 UserHandle.myUserId());
2363 synchronized (ActivityManagerService.this) {
2364 mMemWatchDumpFile = null;
2365 mMemWatchDumpProcName = null;
2366 mMemWatchDumpPid = -1;
2367 mMemWatchDumpUid = -1;
2370 case FOREGROUND_PROFILE_CHANGED_MSG: {
2371 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2373 case REPORT_TIME_TRACKER_MSG: {
2374 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2375 tracker.deliverResult(mContext);
2377 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2378 mUserController.dispatchUserSwitchComplete(msg.arg1);
2380 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2381 mUserController.dispatchLockedBootComplete(msg.arg1);
2383 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2384 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2386 connection.shutdown();
2387 } catch (RemoteException e) {
2388 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2390 // Only a UiAutomation can set this flag and now that
2391 // it is finished we make sure it is reset to its default.
2392 mUserIsMonkey = false;
2394 case IDLE_UIDS_MSG: {
2397 case VR_MODE_CHANGE_MSG: {
2398 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2401 synchronized (ActivityManagerService.this) {
2402 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2403 mWindowManager.disableNonVrUi(disableNonVrUi);
2404 if (disableNonVrUi) {
2405 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2406 // then remove the pinned stack.
2407 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2409 if (pinnedStack != null) {
2410 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2415 case NOTIFY_VR_SLEEPING_MSG: {
2416 notifyVrManagerOfSleepState(msg.arg1 != 0);
2418 case NOTIFY_VR_KEYGUARD_MSG: {
2419 notifyVrManagerOfKeyguardState(msg.arg1 != 0);
2421 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2422 synchronized (ActivityManagerService.this) {
2423 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2424 ProcessRecord r = mLruProcesses.get(i);
2425 if (r.thread != null) {
2427 r.thread.handleTrustStorageUpdate();
2428 } catch (RemoteException ex) {
2429 Slog.w(TAG, "Failed to handle trust storage update for: " +
2430 r.info.processName);
2440 static final int COLLECT_PSS_BG_MSG = 1;
2442 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2444 public void handleMessage(Message msg) {
2446 case COLLECT_PSS_BG_MSG: {
2447 long start = SystemClock.uptimeMillis();
2448 MemInfoReader memInfo = null;
2449 synchronized (ActivityManagerService.this) {
2450 if (mFullPssPending) {
2451 mFullPssPending = false;
2452 memInfo = new MemInfoReader();
2455 if (memInfo != null) {
2456 updateCpuStatsNow();
2457 long nativeTotalPss = 0;
2458 final List<ProcessCpuTracker.Stats> stats;
2459 synchronized (mProcessCpuTracker) {
2460 stats = mProcessCpuTracker.getStats( (st)-> {
2461 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2464 final int N = stats.size();
2465 for (int j = 0; j < N; j++) {
2466 synchronized (mPidsSelfLocked) {
2467 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2468 // This is one of our own processes; skip it.
2472 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2474 memInfo.readMemInfo();
2475 synchronized (ActivityManagerService.this) {
2476 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2477 + (SystemClock.uptimeMillis()-start) + "ms");
2478 final long cachedKb = memInfo.getCachedSizeKb();
2479 final long freeKb = memInfo.getFreeSizeKb();
2480 final long zramKb = memInfo.getZramTotalSizeKb();
2481 final long kernelKb = memInfo.getKernelUsedSizeKb();
2482 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2483 kernelKb*1024, nativeTotalPss*1024);
2484 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2490 long[] tmp = new long[2];
2496 synchronized (ActivityManagerService.this) {
2497 if (mPendingPssProcesses.size() <= 0) {
2498 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2499 "Collected PSS of " + num + " processes in "
2500 + (SystemClock.uptimeMillis() - start) + "ms");
2501 mPendingPssProcesses.clear();
2504 proc = mPendingPssProcesses.remove(0);
2505 procState = proc.pssProcState;
2506 lastPssTime = proc.lastPssTime;
2507 if (proc.thread != null && procState == proc.setProcState
2508 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2509 < SystemClock.uptimeMillis()) {
2517 long pss = Debug.getPss(pid, tmp, null);
2518 synchronized (ActivityManagerService.this) {
2519 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2520 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2522 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2523 SystemClock.uptimeMillis());
2533 public void setSystemProcess() {
2535 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2536 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2537 ServiceManager.addService("meminfo", new MemBinder(this));
2538 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2539 ServiceManager.addService("dbinfo", new DbBinder(this));
2540 if (MONITOR_CPU_USAGE) {
2541 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2543 ServiceManager.addService("permission", new PermissionController(this));
2544 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2546 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2547 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2548 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2550 synchronized (this) {
2551 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2552 app.persistent = true;
2554 app.maxAdj = ProcessList.SYSTEM_ADJ;
2555 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2556 synchronized (mPidsSelfLocked) {
2557 mPidsSelfLocked.put(app.pid, app);
2559 updateLruProcessLocked(app, false, null);
2560 updateOomAdjLocked();
2562 } catch (PackageManager.NameNotFoundException e) {
2563 throw new RuntimeException(
2564 "Unable to find android system package", e);
2568 public void setWindowManager(WindowManagerService wm) {
2569 mWindowManager = wm;
2570 mStackSupervisor.setWindowManager(wm);
2571 mActivityStarter.setWindowManager(wm);
2574 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2575 mUsageStatsService = usageStatsManager;
2578 public void startObservingNativeCrashes() {
2579 final NativeCrashListener ncl = new NativeCrashListener(this);
2583 public IAppOpsService getAppOpsService() {
2584 return mAppOpsService;
2587 static class MemBinder extends Binder {
2588 ActivityManagerService mActivityManagerService;
2589 MemBinder(ActivityManagerService activityManagerService) {
2590 mActivityManagerService = activityManagerService;
2594 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2595 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2596 "meminfo", pw)) return;
2597 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2601 static class GraphicsBinder extends Binder {
2602 ActivityManagerService mActivityManagerService;
2603 GraphicsBinder(ActivityManagerService activityManagerService) {
2604 mActivityManagerService = activityManagerService;
2608 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2609 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2610 "gfxinfo", pw)) return;
2611 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2615 static class DbBinder extends Binder {
2616 ActivityManagerService mActivityManagerService;
2617 DbBinder(ActivityManagerService activityManagerService) {
2618 mActivityManagerService = activityManagerService;
2622 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2623 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2624 "dbinfo", pw)) return;
2625 mActivityManagerService.dumpDbInfo(fd, pw, args);
2629 static class CpuBinder extends Binder {
2630 ActivityManagerService mActivityManagerService;
2631 CpuBinder(ActivityManagerService activityManagerService) {
2632 mActivityManagerService = activityManagerService;
2636 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2637 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2638 "cpuinfo", pw)) return;
2639 synchronized (mActivityManagerService.mProcessCpuTracker) {
2640 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2641 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2642 SystemClock.uptimeMillis()));
2647 public static final class Lifecycle extends SystemService {
2648 private final ActivityManagerService mService;
2650 public Lifecycle(Context context) {
2652 mService = new ActivityManagerService(context);
2656 public void onStart() {
2661 public void onCleanupUser(int userId) {
2662 mService.mBatteryStatsService.onCleanupUser(userId);
2665 public ActivityManagerService getService() {
2671 public ActivityManagerService(Injector injector) {
2672 mInjector = injector;
2673 mContext = mInjector.getContext();
2676 mActivityStarter = null;
2678 mAppOpsService = mInjector.getAppOpsService(null, null);
2679 mBatteryStatsService = null;
2680 mCompatModePackages = null;
2684 mHandlerThread = null;
2685 mIntentFirewall = null;
2686 mKeyguardController = null;
2687 mPermissionReviewRequired = false;
2688 mProcessCpuThread = null;
2689 mProcessStats = null;
2690 mProviderMap = null;
2691 mRecentTasks = null;
2693 mStackSupervisor = null;
2694 mSystemThread = null;
2695 mTaskChangeNotificationController = null;
2696 mUiHandler = injector.getUiHandler(null);
2697 mUserController = null;
2698 mVrController = null;
2701 // Note: This method is invoked on the main thread but may need to attach various
2702 // handlers to other threads. So take care to be explicit about the looper.
2703 public ActivityManagerService(Context systemContext) {
2704 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2705 mInjector = new Injector();
2706 mContext = systemContext;
2708 mFactoryTest = FactoryTest.getMode();
2709 mSystemThread = ActivityThread.currentActivityThread();
2710 mUiContext = mSystemThread.getSystemUiContext();
2712 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2714 mPermissionReviewRequired = mContext.getResources().getBoolean(
2715 com.android.internal.R.bool.config_permissionReviewRequired);
2717 mHandlerThread = new ServiceThread(TAG,
2718 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2719 mHandlerThread.start();
2720 mHandler = new MainHandler(mHandlerThread.getLooper());
2721 mUiHandler = mInjector.getUiHandler(this);
2723 mConstants = new ActivityManagerConstants(this, mHandler);
2725 /* static; one-time init here */
2726 if (sKillHandler == null) {
2727 sKillThread = new ServiceThread(TAG + ":kill",
2728 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2729 sKillThread.start();
2730 sKillHandler = new KillHandler(sKillThread.getLooper());
2733 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2734 "foreground", BROADCAST_FG_TIMEOUT, false);
2735 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2736 "background", BROADCAST_BG_TIMEOUT, true);
2737 mBroadcastQueues[0] = mFgBroadcastQueue;
2738 mBroadcastQueues[1] = mBgBroadcastQueue;
2740 mServices = new ActiveServices(this);
2741 mProviderMap = new ProviderMap(this);
2742 mAppErrors = new AppErrors(mUiContext, this);
2744 // TODO: Move creation of battery stats service outside of activity manager service.
2745 File dataDir = Environment.getDataDirectory();
2746 File systemDir = new File(dataDir, "system");
2748 mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2749 mBatteryStatsService.getActiveStatistics().readLocked();
2750 mBatteryStatsService.scheduleWriteToDisk();
2751 mOnBattery = DEBUG_POWER ? true
2752 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2753 mBatteryStatsService.getActiveStatistics().setCallback(this);
2755 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2757 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2758 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2759 new IAppOpsCallback.Stub() {
2760 @Override public void opChanged(int op, int uid, String packageName) {
2761 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2762 if (mAppOpsService.checkOperation(op, uid, packageName)
2763 != AppOpsManager.MODE_ALLOWED) {
2764 runInBackgroundDisabled(uid);
2770 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2772 mUserController = new UserController(this);
2774 mVrController = new VrController(this);
2776 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2777 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2779 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2780 mUseFifoUiScheduling = true;
2783 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2784 mTempConfig.setToDefaults();
2785 mTempConfig.setLocales(LocaleList.getDefault());
2786 mConfigurationSeq = mTempConfig.seq = 1;
2787 mStackSupervisor = createStackSupervisor();
2788 mStackSupervisor.onConfigurationChanged(mTempConfig);
2789 mKeyguardController = mStackSupervisor.mKeyguardController;
2790 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2791 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2792 mTaskChangeNotificationController =
2793 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2794 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2795 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2797 mProcessCpuThread = new Thread("CpuTracker") {
2800 synchronized (mProcessCpuTracker) {
2801 mProcessCpuInitLatch.countDown();
2802 mProcessCpuTracker.init();
2807 synchronized(this) {
2808 final long now = SystemClock.uptimeMillis();
2809 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2810 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2811 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2812 // + ", write delay=" + nextWriteDelay);
2813 if (nextWriteDelay < nextCpuDelay) {
2814 nextCpuDelay = nextWriteDelay;
2816 if (nextCpuDelay > 0) {
2817 mProcessCpuMutexFree.set(true);
2818 this.wait(nextCpuDelay);
2821 } catch (InterruptedException e) {
2823 updateCpuStatsNow();
2824 } catch (Exception e) {
2825 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2831 Watchdog.getInstance().addMonitor(this);
2832 Watchdog.getInstance().addThread(mHandler);
2835 protected ActivityStackSupervisor createStackSupervisor() {
2836 return new ActivityStackSupervisor(this, mHandler.getLooper());
2839 public void setSystemServiceManager(SystemServiceManager mgr) {
2840 mSystemServiceManager = mgr;
2843 public void setInstaller(Installer installer) {
2844 mInstaller = installer;
2847 private void start() {
2848 removeAllProcessGroups();
2849 mProcessCpuThread.start();
2851 mBatteryStatsService.publish();
2852 mAppOpsService.publish(mContext);
2853 Slog.d("AppOps", "AppOpsService published");
2854 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2855 // Wait for the synchronized block started in mProcessCpuThread,
2856 // so that any other acccess to mProcessCpuTracker from main thread
2857 // will be blocked during mProcessCpuTracker initialization.
2859 mProcessCpuInitLatch.await();
2860 } catch (InterruptedException e) {
2861 Slog.wtf(TAG, "Interrupted wait during start", e);
2862 Thread.currentThread().interrupt();
2863 throw new IllegalStateException("Interrupted wait during start");
2867 void onUserStoppedLocked(int userId) {
2868 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2871 public void initPowerManagement() {
2872 mStackSupervisor.initPowerManagement();
2873 mBatteryStatsService.initPowerManagement();
2874 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2875 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2876 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2877 mVoiceWakeLock.setReferenceCounted(false);
2880 private ArraySet<String> getBackgroundLaunchBroadcasts() {
2881 if (mBackgroundLaunchBroadcasts == null) {
2882 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2884 return mBackgroundLaunchBroadcasts;
2888 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2889 throws RemoteException {
2890 if (code == SYSPROPS_TRANSACTION) {
2891 // We need to tell all apps about the system property change.
2892 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2893 synchronized(this) {
2894 final int NP = mProcessNames.getMap().size();
2895 for (int ip=0; ip<NP; ip++) {
2896 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2897 final int NA = apps.size();
2898 for (int ia=0; ia<NA; ia++) {
2899 ProcessRecord app = apps.valueAt(ia);
2900 if (app.thread != null) {
2901 procs.add(app.thread.asBinder());
2907 int N = procs.size();
2908 for (int i=0; i<N; i++) {
2909 Parcel data2 = Parcel.obtain();
2911 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2912 Binder.FLAG_ONEWAY);
2913 } catch (RemoteException e) {
2919 return super.onTransact(code, data, reply, flags);
2920 } catch (RuntimeException e) {
2921 // The activity manager only throws security exceptions, so let's
2923 if (!(e instanceof SecurityException)) {
2924 Slog.wtf(TAG, "Activity Manager Crash."
2925 + " UID:" + Binder.getCallingUid()
2926 + " PID:" + Binder.getCallingPid()
2927 + " TRANS:" + code, e);
2933 void updateCpuStats() {
2934 final long now = SystemClock.uptimeMillis();
2935 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2938 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2939 synchronized (mProcessCpuThread) {
2940 mProcessCpuThread.notify();
2945 void updateCpuStatsNow() {
2946 synchronized (mProcessCpuTracker) {
2947 mProcessCpuMutexFree.set(false);
2948 final long now = SystemClock.uptimeMillis();
2949 boolean haveNewCpuStats = false;
2951 if (MONITOR_CPU_USAGE &&
2952 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2953 mLastCpuTime.set(now);
2954 mProcessCpuTracker.update();
2955 if (mProcessCpuTracker.hasGoodLastStats()) {
2956 haveNewCpuStats = true;
2957 //Slog.i(TAG, mProcessCpu.printCurrentState());
2958 //Slog.i(TAG, "Total CPU usage: "
2959 // + mProcessCpu.getTotalCpuPercent() + "%");
2961 // Slog the cpu usage if the property is set.
2962 if ("true".equals(SystemProperties.get("events.cpu"))) {
2963 int user = mProcessCpuTracker.getLastUserTime();
2964 int system = mProcessCpuTracker.getLastSystemTime();
2965 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2966 int irq = mProcessCpuTracker.getLastIrqTime();
2967 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2968 int idle = mProcessCpuTracker.getLastIdleTime();
2970 int total = user + system + iowait + irq + softIrq + idle;
2971 if (total == 0) total = 1;
2973 EventLog.writeEvent(EventLogTags.CPU,
2974 ((user+system+iowait+irq+softIrq) * 100) / total,
2975 (user * 100) / total,
2976 (system * 100) / total,
2977 (iowait * 100) / total,
2978 (irq * 100) / total,
2979 (softIrq * 100) / total);
2984 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2985 synchronized(bstats) {
2986 synchronized(mPidsSelfLocked) {
2987 if (haveNewCpuStats) {
2988 if (bstats.startAddingCpuLocked()) {
2991 final int N = mProcessCpuTracker.countStats();
2992 for (int i=0; i<N; i++) {
2993 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2997 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2998 totalUTime += st.rel_utime;
2999 totalSTime += st.rel_stime;
3001 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3002 if (ps == null || !ps.isActive()) {
3003 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3004 pr.info.uid, pr.processName);
3006 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3007 pr.curCpuTime += st.rel_utime + st.rel_stime;
3008 if (pr.lastCpuTime == 0) {
3009 pr.lastCpuTime = pr.curCpuTime;
3012 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3013 if (ps == null || !ps.isActive()) {
3014 st.batteryStats = ps = bstats.getProcessStatsLocked(
3015 bstats.mapUid(st.uid), st.name);
3017 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3020 final int userTime = mProcessCpuTracker.getLastUserTime();
3021 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3022 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3023 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3024 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3025 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3026 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3027 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3032 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3033 mLastWriteTime = now;
3034 mBatteryStatsService.scheduleWriteToDisk();
3041 public void batteryNeedsCpuUpdate() {
3042 updateCpuStatsNow();
3046 public void batteryPowerChanged(boolean onBattery) {
3047 // When plugging in, update the CPU stats first before changing
3049 updateCpuStatsNow();
3050 synchronized (this) {
3051 synchronized(mPidsSelfLocked) {
3052 mOnBattery = DEBUG_POWER ? true : onBattery;
3058 public void batterySendBroadcast(Intent intent) {
3059 synchronized (this) {
3060 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3061 AppOpsManager.OP_NONE, null, false, false,
3062 -1, SYSTEM_UID, UserHandle.USER_ALL);
3067 * Initialize the application bind args. These are passed to each
3068 * process when the bindApplication() IPC is sent to the process. They're
3069 * lazily setup to make sure the services are running when they're asked for.
3071 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3072 // Isolated processes won't get this optimization, so that we don't
3073 // violate the rules about which services they have access to.
3075 if (mIsolatedAppBindArgs == null) {
3076 mIsolatedAppBindArgs = new HashMap<>();
3077 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3079 return mIsolatedAppBindArgs;
3082 if (mAppBindArgs == null) {
3083 mAppBindArgs = new HashMap<>();
3085 // Setup the application init args
3086 mAppBindArgs.put("package", ServiceManager.getService("package"));
3087 mAppBindArgs.put("window", ServiceManager.getService("window"));
3088 mAppBindArgs.put(Context.ALARM_SERVICE,
3089 ServiceManager.getService(Context.ALARM_SERVICE));
3091 return mAppBindArgs;
3095 * Update AMS states when an activity is resumed. This should only be called by
3096 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3098 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3099 final TaskRecord task = r.getTask();
3100 if (task.isApplicationTask()) {
3101 if (mCurAppTimeTracker != r.appTimeTracker) {
3102 // We are switching app tracking. Complete the current one.
3103 if (mCurAppTimeTracker != null) {
3104 mCurAppTimeTracker.stop();
3105 mHandler.obtainMessage(
3106 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3107 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3108 mCurAppTimeTracker = null;
3110 if (r.appTimeTracker != null) {
3111 mCurAppTimeTracker = r.appTimeTracker;
3112 startTimeTrackingFocusedActivityLocked();
3115 startTimeTrackingFocusedActivityLocked();
3118 r.appTimeTracker = null;
3120 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3121 // TODO: Probably not, because we don't want to resume voice on switching
3122 // back to this activity
3123 if (task.voiceInteractor != null) {
3124 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3126 finishRunningVoiceLocked();
3128 if (mLastResumedActivity != null) {
3129 final IVoiceInteractionSession session;
3131 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3132 if (lastResumedActivityTask != null
3133 && lastResumedActivityTask.voiceSession != null) {
3134 session = lastResumedActivityTask.voiceSession;
3136 session = mLastResumedActivity.voiceSession;
3139 if (session != null) {
3140 // We had been in a voice interaction session, but now focused has
3141 // move to something different. Just finish the session, we can't
3142 // return to it and retain the proper state and synchronization with
3143 // the voice interaction service.
3144 finishVoiceTask(session);
3149 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3150 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3151 mHandler.obtainMessage(
3152 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3154 mLastResumedActivity = r;
3156 mWindowManager.setFocusedApp(r.appToken, true);
3158 applyUpdateLockStateLocked(r);
3159 applyUpdateVrModeLocked(r);
3161 EventLogTags.writeAmSetResumedActivity(
3162 r == null ? -1 : r.userId,
3163 r == null ? "NULL" : r.shortComponentName,
3168 public void setFocusedStack(int stackId) {
3169 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3170 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3171 final long callingId = Binder.clearCallingIdentity();
3173 synchronized (this) {
3174 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3175 if (stack == null) {
3178 final ActivityRecord r = stack.topRunningActivityLocked();
3179 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3180 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3184 Binder.restoreCallingIdentity(callingId);
3189 public void setFocusedTask(int taskId) {
3190 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3191 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3192 final long callingId = Binder.clearCallingIdentity();
3194 synchronized (this) {
3195 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3199 final ActivityRecord r = task.topRunningActivityLocked();
3200 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3201 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3205 Binder.restoreCallingIdentity(callingId);
3209 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3211 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3212 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3213 mTaskChangeNotificationController.registerTaskStackListener(listener);
3217 * Unregister a task stack listener so that it stops receiving callbacks.
3220 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3221 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3222 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3226 public void notifyActivityDrawn(IBinder token) {
3227 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3228 synchronized (this) {
3229 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3231 r.getStack().notifyActivityDrawnLocked(r);
3236 final void applyUpdateLockStateLocked(ActivityRecord r) {
3237 // Modifications to the UpdateLock state are done on our handler, outside
3238 // the activity manager's locks. The new state is determined based on the
3239 // state *now* of the relevant activity record. The object is passed to
3240 // the handler solely for logging detail, not to be consulted/modified.
3241 final boolean nextState = r != null && r.immersive;
3242 mHandler.sendMessage(
3243 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3246 final void applyUpdateVrModeLocked(ActivityRecord r) {
3247 // VR apps are expected to run in a main display. If an app is turning on VR for
3248 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3249 // fullscreen stack before enabling VR Mode.
3250 // TODO: The goal of this code is to keep the VR app on the main display. When the
3251 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3252 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3253 // option would be a better choice here.
3254 if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3255 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3256 + " to main stack for VR");
3257 moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3259 mHandler.sendMessage(
3260 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3263 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3264 mHandler.sendMessage(
3265 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3268 private void notifyVrManagerOfSleepState(boolean isSleeping) {
3269 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3270 if (vrService == null) {
3273 vrService.onSleepStateChanged(isSleeping);
3276 private void sendNotifyVrManagerOfKeyguardState(boolean isShowing) {
3277 mHandler.sendMessage(
3278 mHandler.obtainMessage(NOTIFY_VR_KEYGUARD_MSG, isShowing ? 1 : 0, 0));
3281 private void notifyVrManagerOfKeyguardState(boolean isShowing) {
3282 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3283 if (vrService == null) {
3286 vrService.onKeyguardStateChanged(isShowing);
3289 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3290 Message msg = Message.obtain();
3291 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3292 msg.obj = r.getTask().askedCompatMode ? null : r;
3293 mUiHandler.sendMessage(msg);
3296 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3297 final Configuration globalConfig = getGlobalConfiguration();
3298 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3299 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3300 final Message msg = Message.obtain();
3301 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3303 mUiHandler.sendMessage(msg);
3307 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3308 String what, Object obj, ProcessRecord srcApp) {
3309 app.lastActivityTime = now;
3311 if (app.activities.size() > 0) {
3312 // Don't want to touch dependent processes that are hosting activities.
3316 int lrui = mLruProcesses.lastIndexOf(app);
3318 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3319 + what + " " + obj + " from " + srcApp);
3323 if (lrui >= index) {
3324 // Don't want to cause this to move dependent processes *back* in the
3325 // list as if they were less frequently used.
3329 if (lrui >= mLruProcessActivityStart) {
3330 // Don't want to touch dependent processes that are hosting activities.
3334 mLruProcesses.remove(lrui);
3338 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3339 + " in LRU list: " + app);
3340 mLruProcesses.add(index, app);
3344 static void killProcessGroup(int uid, int pid) {
3345 if (sKillHandler != null) {
3346 sKillHandler.sendMessage(
3347 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3349 Slog.w(TAG, "Asked to kill process group before system bringup!");
3350 Process.killProcessGroup(uid, pid);
3354 final void removeLruProcessLocked(ProcessRecord app) {
3355 int lrui = mLruProcesses.lastIndexOf(app);
3358 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3359 killProcessQuiet(app.pid);
3360 killProcessGroup(app.uid, app.pid);
3362 if (lrui <= mLruProcessActivityStart) {
3363 mLruProcessActivityStart--;
3365 if (lrui <= mLruProcessServiceStart) {
3366 mLruProcessServiceStart--;
3368 mLruProcesses.remove(lrui);
3372 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3373 ProcessRecord client) {
3374 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3375 || app.treatLikeActivity;
3376 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3377 if (!activityChange && hasActivity) {
3378 // The process has activities, so we are only allowing activity-based adjustments
3379 // to move it. It should be kept in the front of the list with other
3380 // processes that have activities, and we don't want those to change their
3381 // order except due to activity operations.
3386 final long now = SystemClock.uptimeMillis();
3387 app.lastActivityTime = now;
3389 // First a quick reject: if the app is already at the position we will
3390 // put it, then there is nothing to do.
3392 final int N = mLruProcesses.size();
3393 if (N > 0 && mLruProcesses.get(N-1) == app) {
3394 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3398 if (mLruProcessServiceStart > 0
3399 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3400 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3405 int lrui = mLruProcesses.lastIndexOf(app);
3407 if (app.persistent && lrui >= 0) {
3408 // We don't care about the position of persistent processes, as long as
3409 // they are in the list.
3410 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3414 /* In progress: compute new position first, so we can avoid doing work
3415 if the process is not actually going to move. Not yet working.
3418 boolean inActivity = false, inService = false;
3420 // Process has activities, put it at the very tipsy-top.
3421 addIndex = mLruProcesses.size();
3422 nextIndex = mLruProcessServiceStart;
3424 } else if (hasService) {
3425 // Process has services, put it at the top of the service list.
3426 addIndex = mLruProcessActivityStart;
3427 nextIndex = mLruProcessServiceStart;
3431 // Process not otherwise of interest, it goes to the top of the non-service area.
3432 addIndex = mLruProcessServiceStart;
3433 if (client != null) {
3434 int clientIndex = mLruProcesses.lastIndexOf(client);
3435 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3437 if (clientIndex >= 0 && addIndex > clientIndex) {
3438 addIndex = clientIndex;
3441 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3444 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3445 + mLruProcessActivityStart + "): " + app);
3449 if (lrui < mLruProcessActivityStart) {
3450 mLruProcessActivityStart--;
3452 if (lrui < mLruProcessServiceStart) {
3453 mLruProcessServiceStart--;
3456 if (addIndex > lrui) {
3459 if (nextIndex > lrui) {
3463 mLruProcesses.remove(lrui);
3467 mLruProcesses.add(addIndex, app);
3469 mLruProcessActivityStart++;
3472 mLruProcessActivityStart++;
3478 final int N = mLruProcesses.size();
3479 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3480 // Process doesn't have activities, but has clients with
3481 // activities... move it up, but one below the top (the top
3482 // should always have a real activity).
3483 if (DEBUG_LRU) Slog.d(TAG_LRU,
3484 "Adding to second-top of LRU activity list: " + app);
3485 mLruProcesses.add(N - 1, app);
3486 // To keep it from spamming the LRU list (by making a bunch of clients),
3487 // we will push down any other entries owned by the app.
3488 final int uid = app.info.uid;
3489 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3490 ProcessRecord subProc = mLruProcesses.get(i);
3491 if (subProc.info.uid == uid) {
3492 // We want to push this one down the list. If the process after
3493 // it is for the same uid, however, don't do so, because we don't
3494 // want them internally to be re-ordered.
3495 if (mLruProcesses.get(i - 1).info.uid != uid) {
3496 if (DEBUG_LRU) Slog.d(TAG_LRU,
3497 "Pushing uid " + uid + " swapping at " + i + ": "
3498 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3499 ProcessRecord tmp = mLruProcesses.get(i);
3500 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3501 mLruProcesses.set(i - 1, tmp);
3505 // A gap, we can stop here.
3510 // Process has activities, put it at the very tipsy-top.
3511 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3512 mLruProcesses.add(app);
3514 nextIndex = mLruProcessServiceStart;
3515 } else if (hasService) {
3516 // Process has services, put it at the top of the service list.
3517 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3518 mLruProcesses.add(mLruProcessActivityStart, app);
3519 nextIndex = mLruProcessServiceStart;
3520 mLruProcessActivityStart++;
3522 // Process not otherwise of interest, it goes to the top of the non-service area.
3523 int index = mLruProcessServiceStart;
3524 if (client != null) {
3525 // If there is a client, don't allow the process to be moved up higher
3526 // in the list than that client.
3527 int clientIndex = mLruProcesses.lastIndexOf(client);
3528 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3529 + " when updating " + app);
3530 if (clientIndex <= lrui) {
3531 // Don't allow the client index restriction to push it down farther in the
3532 // list than it already is.
3535 if (clientIndex >= 0 && index > clientIndex) {
3536 index = clientIndex;
3539 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3540 mLruProcesses.add(index, app);
3541 nextIndex = index-1;
3542 mLruProcessActivityStart++;
3543 mLruProcessServiceStart++;
3546 // If the app is currently using a content provider or service,
3547 // bump those processes as well.
3548 for (int j=app.connections.size()-1; j>=0; j--) {
3549 ConnectionRecord cr = app.connections.valueAt(j);
3550 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3551 && cr.binding.service.app != null
3552 && cr.binding.service.app.lruSeq != mLruSeq
3553 && !cr.binding.service.app.persistent) {
3554 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3555 "service connection", cr, app);
3558 for (int j=app.conProviders.size()-1; j>=0; j--) {
3559 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3560 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3561 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3562 "provider reference", cpr, app);
3567 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3568 if (uid == SYSTEM_UID) {
3569 // The system gets to run in any process. If there are multiple
3570 // processes with the same uid, just pick the first (this
3571 // should never happen).
3572 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3573 if (procs == null) return null;
3574 final int procCount = procs.size();
3575 for (int i = 0; i < procCount; i++) {
3576 final int procUid = procs.keyAt(i);
3577 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3578 // Don't use an app process or different user process for system component.
3581 return procs.valueAt(i);
3584 ProcessRecord proc = mProcessNames.get(processName, uid);
3585 if (false && proc != null && !keepIfLarge
3586 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3587 && proc.lastCachedPss >= 4000) {
3588 // Turn this condition on to cause killing to happen regularly, for testing.
3589 if (proc.baseProcessTracker != null) {
3590 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3592 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3593 } else if (proc != null && !keepIfLarge
3594 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3595 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3596 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3597 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3598 if (proc.baseProcessTracker != null) {
3599 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3601 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3607 void notifyPackageUse(String packageName, int reason) {
3608 synchronized(this) {
3609 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3613 boolean isNextTransitionForward() {
3614 int transit = mWindowManager.getPendingAppTransition();
3615 return transit == TRANSIT_ACTIVITY_OPEN
3616 || transit == TRANSIT_TASK_OPEN
3617 || transit == TRANSIT_TASK_TO_FRONT;
3620 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3621 String processName, String abiOverride, int uid, Runnable crashHandler) {
3622 synchronized(this) {
3623 ApplicationInfo info = new ApplicationInfo();
3624 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3625 // For isolated processes, the former contains the parent's uid and the latter the
3626 // actual uid of the isolated process.
3627 // In the special case introduced by this method (which is, starting an isolated
3628 // process directly from the SystemServer without an actual parent app process) the
3629 // closest thing to a parent's uid is SYSTEM_UID.
3630 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3631 // the |isolated| logic in the ProcessRecord constructor.
3632 info.uid = SYSTEM_UID;
3633 info.processName = processName;
3634 info.className = entryPoint;
3635 info.packageName = "android";
3636 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3637 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3638 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3639 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3640 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3642 return proc != null ? proc.pid : 0;
3646 final ProcessRecord startProcessLocked(String processName,
3647 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3648 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3649 boolean isolated, boolean keepIfLarge) {
3650 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3651 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3652 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3653 null /* crashHandler */);
3656 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3657 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3658 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3659 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3660 long startTime = SystemClock.elapsedRealtime();
3663 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3664 checkTime(startTime, "startProcess: after getProcessRecord");
3666 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3667 // If we are in the background, then check to see if this process
3668 // is bad. If so, we will just silently fail.
3669 if (mAppErrors.isBadProcessLocked(info)) {
3670 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3671 + "/" + info.processName);
3675 // When the user is explicitly starting a process, then clear its
3676 // crash count so that we won't make it bad until they see at
3677 // least one crash dialog again, and make the process good again
3678 // if it had been bad.
3679 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3680 + "/" + info.processName);
3681 mAppErrors.resetProcessCrashTimeLocked(info);
3682 if (mAppErrors.isBadProcessLocked(info)) {
3683 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3684 UserHandle.getUserId(info.uid), info.uid,
3686 mAppErrors.clearBadProcessLocked(info);
3693 // If this is an isolated process, it can't re-use an existing process.
3697 // We don't have to do anything more if:
3698 // (1) There is an existing application record; and
3699 // (2) The caller doesn't think it is dead, OR there is no thread
3700 // object attached to it so we know it couldn't have crashed; and
3701 // (3) There is a pid assigned to it, so it is either starting or
3703 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3704 + " app=" + app + " knownToBeDead=" + knownToBeDead
3705 + " thread=" + (app != null ? app.thread : null)
3706 + " pid=" + (app != null ? app.pid : -1));
3707 if (app != null && app.pid > 0) {
3708 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3709 // We already have the app running, or are waiting for it to
3710 // come up (we have a pid but not yet its thread), so keep it.
3711 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3712 // If this is a new package in the process, add the package to the list
3713 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3714 checkTime(startTime, "startProcess: done, added package to proc");
3718 // An application record is attached to a previous process,
3720 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3721 checkTime(startTime, "startProcess: bad proc running, killing");
3722 killProcessGroup(app.uid, app.pid);
3723 handleAppDiedLocked(app, true, true);
3724 checkTime(startTime, "startProcess: done killing old proc");
3727 String hostingNameStr = hostingName != null
3728 ? hostingName.flattenToShortString() : null;
3731 checkTime(startTime, "startProcess: creating new process record");
3732 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3734 Slog.w(TAG, "Failed making new process record for "
3735 + processName + "/" + info.uid + " isolated=" + isolated);
3738 app.crashHandler = crashHandler;
3739 checkTime(startTime, "startProcess: done creating new process record");
3741 // If this is a new package in the process, add the package to the list
3742 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3743 checkTime(startTime, "startProcess: added package to existing proc");
3746 // If the system is not ready yet, then hold off on starting this
3747 // process until it is.
3748 if (!mProcessesReady
3749 && !isAllowedWhileBooting(info)
3750 && !allowWhileBooting) {
3751 if (!mProcessesOnHold.contains(app)) {
3752 mProcessesOnHold.add(app);
3754 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3755 "System not ready, putting on hold: " + app);
3756 checkTime(startTime, "startProcess: returning with proc on hold");
3760 checkTime(startTime, "startProcess: stepping in to startProcess");
3762 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3763 checkTime(startTime, "startProcess: done starting proc!");
3764 return (app.pid != 0) ? app : null;
3767 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3768 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3771 private final void startProcessLocked(ProcessRecord app,
3772 String hostingType, String hostingNameStr) {
3773 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3774 null /* entryPoint */, null /* entryPointArgs */);
3777 private final void startProcessLocked(ProcessRecord app, String hostingType,
3778 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3779 long startTime = SystemClock.elapsedRealtime();
3780 if (app.pid > 0 && app.pid != MY_PID) {
3781 checkTime(startTime, "startProcess: removing from pids map");
3782 synchronized (mPidsSelfLocked) {
3783 mPidsSelfLocked.remove(app.pid);
3784 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3786 checkTime(startTime, "startProcess: done removing from pids map");
3790 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3791 "startProcessLocked removing on hold: " + app);
3792 mProcessesOnHold.remove(app);
3794 checkTime(startTime, "startProcess: starting to update cpu stats");
3796 checkTime(startTime, "startProcess: done updating cpu stats");
3800 final int userId = UserHandle.getUserId(app.uid);
3801 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3802 } catch (RemoteException e) {
3803 throw e.rethrowAsRuntimeException();
3808 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3809 if (!app.isolated) {
3810 int[] permGids = null;
3812 checkTime(startTime, "startProcess: getting gids from package manager");
3813 final IPackageManager pm = AppGlobals.getPackageManager();
3814 permGids = pm.getPackageGids(app.info.packageName,
3815 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3816 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3817 StorageManagerInternal.class);
3818 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3819 app.info.packageName);
3820 } catch (RemoteException e) {
3821 throw e.rethrowAsRuntimeException();
3825 * Add shared application and profile GIDs so applications can share some
3826 * resources like shared libraries and access user-wide resources
3828 if (ArrayUtils.isEmpty(permGids)) {
3831 gids = new int[permGids.length + 3];
3832 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3834 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3835 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3836 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3838 checkTime(startTime, "startProcess: building args");
3839 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3840 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3841 && mTopComponent != null
3842 && app.processName.equals(mTopComponent.getPackageName())) {
3845 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3846 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3851 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3852 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3853 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3854 // Also turn on CheckJNI for debuggable apps. It's quite
3855 // awkward to turn on otherwise.
3856 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3858 // Run the app in safe mode if its manifest requests so or the
3859 // system is booted in safe mode.
3860 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3861 mSafeMode == true) {
3862 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3864 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3865 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3867 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3868 if ("true".equals(genDebugInfoProperty)) {
3869 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3871 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3872 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3874 if ("1".equals(SystemProperties.get("debug.assert"))) {
3875 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3877 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3878 // Enable all debug flags required by the native debugger.
3879 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3880 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3881 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3882 mNativeDebuggingApp = null;
3885 String invokeWith = null;
3886 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3887 // Debuggable apps may include a wrapper script with their library directory.
3888 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3889 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3891 if (new File(wrapperFileName).exists()) {
3892 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3895 StrictMode.setThreadPolicy(oldPolicy);
3899 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3900 if (requiredAbi == null) {
3901 requiredAbi = Build.SUPPORTED_ABIS[0];
3904 String instructionSet = null;
3905 if (app.info.primaryCpuAbi != null) {
3906 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3910 app.requiredAbi = requiredAbi;
3911 app.instructionSet = instructionSet;
3913 // the per-user SELinux context must be set
3914 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3915 Slog.wtf(TAG, "SELinux tag not defined",
3916 new IllegalStateException("SELinux tag not defined for "
3917 + app.info.packageName + " (uid " + app.uid + ")"));
3919 final String seInfo = app.info.seInfo
3920 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3921 // Start the process. It will either succeed and return a result containing
3922 // the PID of the new process, or else throw a RuntimeException.
3923 boolean isActivityProcess = (entryPoint == null);
3924 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3925 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3927 checkTime(startTime, "startProcess: asking zygote to start proc");
3928 ProcessStartResult startResult;
3929 if (hostingType.equals("webview_service")) {
3930 startResult = startWebView(entryPoint,
3931 app.processName, uid, uid, gids, debugFlags, mountExternal,
3932 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3933 app.info.dataDir, null, entryPointArgs);
3935 startResult = Process.start(entryPoint,
3936 app.processName, uid, uid, gids, debugFlags, mountExternal,
3937 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3938 app.info.dataDir, invokeWith, entryPointArgs);
3940 checkTime(startTime, "startProcess: returned from zygote!");
3941 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3943 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3944 checkTime(startTime, "startProcess: done updating battery stats");
3946 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3947 UserHandle.getUserId(uid), startResult.pid, uid,
3948 app.processName, hostingType,
3949 hostingNameStr != null ? hostingNameStr : "");
3952 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3953 seInfo, app.info.sourceDir, startResult.pid);
3954 } catch (RemoteException ex) {
3958 if (app.persistent) {
3959 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3962 checkTime(startTime, "startProcess: building log message");
3963 StringBuilder buf = mStringBuilder;
3965 buf.append("Start proc ");
3966 buf.append(startResult.pid);
3968 buf.append(app.processName);
3970 UserHandle.formatUid(buf, uid);
3971 if (!isActivityProcess) {
3973 buf.append(entryPoint);
3976 buf.append(" for ");
3977 buf.append(hostingType);
3978 if (hostingNameStr != null) {
3980 buf.append(hostingNameStr);
3982 Slog.i(TAG, buf.toString());
3983 app.setPid(startResult.pid);
3984 app.usingWrapper = startResult.usingWrapper;
3985 app.removed = false;
3987 app.killedByAm = false;
3988 checkTime(startTime, "startProcess: starting to update pids map");
3989 ProcessRecord oldApp;
3990 synchronized (mPidsSelfLocked) {
3991 oldApp = mPidsSelfLocked.get(startResult.pid);
3993 // If there is already an app occupying that pid that hasn't been cleaned up
3994 if (oldApp != null && !app.isolated) {
3995 // Clean up anything relating to this pid first
3996 Slog.w(TAG, "Reusing pid " + startResult.pid
3997 + " while app is still mapped to it");
3998 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3999 true /*replacingPid*/);
4001 synchronized (mPidsSelfLocked) {
4002 this.mPidsSelfLocked.put(startResult.pid, app);
4003 if (isActivityProcess) {
4004 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4006 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4007 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4010 checkTime(startTime, "startProcess: done updating pids map");
4011 } catch (RuntimeException e) {
4012 Slog.e(TAG, "Failure starting process " + app.processName, e);
4014 // Something went very wrong while trying to start this process; one
4015 // common case is when the package is frozen due to an active
4016 // upgrade. To recover, clean up any active bookkeeping related to
4017 // starting this process. (We already invoked this method once when
4018 // the package was initially frozen through KILL_APPLICATION_MSG, so
4019 // it doesn't hurt to use it again.)
4020 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4021 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4025 void updateUsageStats(ActivityRecord component, boolean resumed) {
4026 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4027 "updateUsageStats: comp=" + component + "res=" + resumed);
4028 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4030 if (mUsageStatsService != null) {
4031 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4032 UsageEvents.Event.MOVE_TO_FOREGROUND);
4034 synchronized (stats) {
4035 stats.noteActivityResumedLocked(component.app.uid);
4038 if (mUsageStatsService != null) {
4039 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4040 UsageEvents.Event.MOVE_TO_BACKGROUND);
4042 synchronized (stats) {
4043 stats.noteActivityPausedLocked(component.app.uid);
4048 Intent getHomeIntent() {
4049 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4050 intent.setComponent(mTopComponent);
4051 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4052 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4053 intent.addCategory(Intent.CATEGORY_HOME);
4058 boolean startHomeActivityLocked(int userId, String reason) {
4059 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4060 && mTopAction == null) {
4061 // We are running in factory test mode, but unable to find
4062 // the factory test app, so just sit around displaying the
4063 // error message and don't try to start anything.
4066 Intent intent = getHomeIntent();
4067 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4068 if (aInfo != null) {
4069 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4070 // Don't do this if the home app is currently being
4072 aInfo = new ActivityInfo(aInfo);
4073 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4074 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4075 aInfo.applicationInfo.uid, true);
4076 if (app == null || app.instr == null) {
4077 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4078 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4079 // For ANR debugging to verify if the user activity is the one that actually
4081 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4082 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4085 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4091 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4092 ActivityInfo ai = null;
4093 ComponentName comp = intent.getComponent();
4097 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4099 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4101 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4105 ai = info.activityInfo;
4108 } catch (RemoteException e) {
4116 * Starts the "new version setup screen" if appropriate.
4118 void startSetupActivityLocked() {
4119 // Only do this once per boot.
4120 if (mCheckedForSetup) {
4124 // We will show this screen if the current one is a different
4125 // version than the last one shown, and we are not running in
4126 // low-level factory test mode.
4127 final ContentResolver resolver = mContext.getContentResolver();
4128 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4129 Settings.Global.getInt(resolver,
4130 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4131 mCheckedForSetup = true;
4133 // See if we should be showing the platform update setup UI.
4134 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4135 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4136 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4137 if (!ris.isEmpty()) {
4138 final ResolveInfo ri = ris.get(0);
4139 String vers = ri.activityInfo.metaData != null
4140 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4142 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4143 vers = ri.activityInfo.applicationInfo.metaData.getString(
4144 Intent.METADATA_SETUP_VERSION);
4146 String lastVers = Settings.Secure.getString(
4147 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4148 if (vers != null && !vers.equals(lastVers)) {
4149 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4150 intent.setComponent(new ComponentName(
4151 ri.activityInfo.packageName, ri.activityInfo.name));
4152 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4153 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4154 null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4160 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4161 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4164 void enforceNotIsolatedCaller(String caller) {
4165 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4166 throw new SecurityException("Isolated process not allowed to call " + caller);
4170 void enforceShellRestriction(String restriction, int userHandle) {
4171 if (Binder.getCallingUid() == SHELL_UID) {
4172 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4173 throw new SecurityException("Shell does not have permission to access user "
4180 public int getFrontActivityScreenCompatMode() {
4181 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4182 synchronized (this) {
4183 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4188 public void setFrontActivityScreenCompatMode(int mode) {
4189 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4190 "setFrontActivityScreenCompatMode");
4191 synchronized (this) {
4192 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4197 public int getPackageScreenCompatMode(String packageName) {
4198 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4199 synchronized (this) {
4200 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4205 public void setPackageScreenCompatMode(String packageName, int mode) {
4206 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4207 "setPackageScreenCompatMode");
4208 synchronized (this) {
4209 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4214 public boolean getPackageAskScreenCompat(String packageName) {
4215 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4216 synchronized (this) {
4217 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4222 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4223 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4224 "setPackageAskScreenCompat");
4225 synchronized (this) {
4226 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4230 private boolean hasUsageStatsPermission(String callingPackage) {
4231 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4232 Binder.getCallingUid(), callingPackage);
4233 if (mode == AppOpsManager.MODE_DEFAULT) {
4234 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4235 == PackageManager.PERMISSION_GRANTED;
4237 return mode == AppOpsManager.MODE_ALLOWED;
4241 public int getPackageProcessState(String packageName, String callingPackage) {
4242 if (!hasUsageStatsPermission(callingPackage)) {
4243 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4244 "getPackageProcessState");
4247 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4248 synchronized (this) {
4249 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4250 final ProcessRecord proc = mLruProcesses.get(i);
4251 if (procState > proc.setProcState) {
4252 if (proc.pkgList.containsKey(packageName) ||
4253 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4254 procState = proc.setProcState;
4263 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4264 throws RemoteException {
4265 synchronized (this) {
4266 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4268 throw new IllegalArgumentException("Unknown process: " + process);
4270 if (app.thread == null) {
4271 throw new IllegalArgumentException("Process has no app thread");
4273 if (app.trimMemoryLevel >= level) {
4274 throw new IllegalArgumentException(
4275 "Unable to set a higher trim level than current level");
4277 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4278 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4279 throw new IllegalArgumentException("Unable to set a background trim level "
4280 + "on a foreground process");
4282 app.thread.scheduleTrimMemory(level);
4283 app.trimMemoryLevel = level;
4288 private void dispatchProcessesChanged() {
4290 synchronized (this) {
4291 N = mPendingProcessChanges.size();
4292 if (mActiveProcessChanges.length < N) {
4293 mActiveProcessChanges = new ProcessChangeItem[N];
4295 mPendingProcessChanges.toArray(mActiveProcessChanges);
4296 mPendingProcessChanges.clear();
4297 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4298 "*** Delivering " + N + " process changes");
4301 int i = mProcessObservers.beginBroadcast();
4304 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4305 if (observer != null) {
4307 for (int j=0; j<N; j++) {
4308 ProcessChangeItem item = mActiveProcessChanges[j];
4309 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4310 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4311 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4312 + item.uid + ": " + item.foregroundActivities);
4313 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4314 item.foregroundActivities);
4317 } catch (RemoteException e) {
4321 mProcessObservers.finishBroadcast();
4323 synchronized (this) {
4324 for (int j=0; j<N; j++) {
4325 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4330 private void dispatchProcessDied(int pid, int uid) {
4331 int i = mProcessObservers.beginBroadcast();
4334 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4335 if (observer != null) {
4337 observer.onProcessDied(pid, uid);
4338 } catch (RemoteException e) {
4342 mProcessObservers.finishBroadcast();
4346 void dispatchUidsChanged() {
4348 synchronized (this) {
4349 N = mPendingUidChanges.size();
4350 if (mActiveUidChanges.length < N) {
4351 mActiveUidChanges = new UidRecord.ChangeItem[N];
4353 for (int i=0; i<N; i++) {
4354 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4355 mActiveUidChanges[i] = change;
4356 if (change.uidRecord != null) {
4357 change.uidRecord.pendingChange = null;
4358 change.uidRecord = null;
4361 mPendingUidChanges.clear();
4362 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4363 "*** Delivering " + N + " uid changes");
4366 int i = mUidObservers.beginBroadcast();
4369 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4370 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4372 mUidObservers.finishBroadcast();
4374 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4375 for (int j = 0; j < N; ++j) {
4376 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4377 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4378 mValidateUids.remove(item.uid);
4380 UidRecord validateUid = mValidateUids.get(item.uid);
4381 if (validateUid == null) {
4382 validateUid = new UidRecord(item.uid);
4383 mValidateUids.put(item.uid, validateUid);
4385 if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4386 validateUid.idle = true;
4387 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4388 validateUid.idle = false;
4390 validateUid.curProcState = validateUid.setProcState = item.processState;
4391 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4396 synchronized (this) {
4397 for (int j = 0; j < N; j++) {
4398 mAvailUidChanges.add(mActiveUidChanges[j]);
4403 private void dispatchUidsChangedForObserver(IUidObserver observer,
4404 UidObserverRegistration reg, int changesSize) {
4405 if (observer == null) {
4409 for (int j = 0; j < changesSize; j++) {
4410 UidRecord.ChangeItem item = mActiveUidChanges[j];
4411 final int change = item.change;
4412 if (change == UidRecord.CHANGE_PROCSTATE &&
4413 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4414 // No-op common case: no significant change, the observer is not
4415 // interested in all proc state changes.
4418 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4419 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4420 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4421 "UID idle uid=" + item.uid);
4422 observer.onUidIdle(item.uid, item.ephemeral);
4424 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4425 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4426 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4427 "UID active uid=" + item.uid);
4428 observer.onUidActive(item.uid);
4431 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4432 if ((change & UidRecord.CHANGE_CACHED) != 0) {
4433 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4434 "UID cached uid=" + item.uid);
4435 observer.onUidCachedChanged(item.uid, true);
4436 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4437 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4438 "UID active uid=" + item.uid);
4439 observer.onUidCachedChanged(item.uid, false);
4442 if ((change & UidRecord.CHANGE_GONE) != 0) {
4443 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4444 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4445 "UID gone uid=" + item.uid);
4446 observer.onUidGone(item.uid, item.ephemeral);
4448 if (reg.lastProcStates != null) {
4449 reg.lastProcStates.delete(item.uid);
4452 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4453 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4454 "UID CHANGED uid=" + item.uid
4455 + ": " + item.processState);
4456 boolean doReport = true;
4457 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4458 final int lastState = reg.lastProcStates.get(item.uid,
4459 ActivityManager.PROCESS_STATE_UNKNOWN);
4460 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4461 final boolean lastAboveCut = lastState <= reg.cutpoint;
4462 final boolean newAboveCut = item.processState <= reg.cutpoint;
4463 doReport = lastAboveCut != newAboveCut;
4465 doReport = item.processState
4466 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4470 if (reg.lastProcStates != null) {
4471 reg.lastProcStates.put(item.uid, item.processState);
4473 observer.onUidStateChanged(item.uid, item.processState,
4479 } catch (RemoteException e) {
4483 void dispatchOomAdjObserver(String msg) {
4484 OomAdjObserver observer;
4485 synchronized (this) {
4486 observer = mCurOomAdjObserver;
4489 if (observer != null) {
4490 observer.onOomAdjMessage(msg);
4494 void setOomAdjObserver(int uid, OomAdjObserver observer) {
4495 synchronized (this) {
4496 mCurOomAdjUid = uid;
4497 mCurOomAdjObserver = observer;
4501 void clearOomAdjObserver() {
4502 synchronized (this) {
4504 mCurOomAdjObserver = null;
4508 void reportOomAdjMessageLocked(String tag, String msg) {
4510 if (mCurOomAdjObserver != null) {
4511 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4516 public final int startActivity(IApplicationThread caller, String callingPackage,
4517 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4518 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4519 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4520 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4521 UserHandle.getCallingUserId());
4525 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4526 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4527 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4528 enforceNotIsolatedCaller("startActivity");
4529 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4530 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4531 // TODO: Switch to user app stacks here.
4532 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4533 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4534 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4538 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4539 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4540 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4543 // This is very dangerous -- it allows you to perform a start activity (including
4544 // permission grants) as any app that may launch one of your own activities. So
4545 // we will only allow this to be done from activities that are part of the core framework,
4546 // and then only when they are running as the system.
4547 final ActivityRecord sourceRecord;
4548 final int targetUid;
4549 final String targetPackage;
4550 synchronized (this) {
4551 if (resultTo == null) {
4552 throw new SecurityException("Must be called from an activity");
4554 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4555 if (sourceRecord == null) {
4556 throw new SecurityException("Called with bad activity token: " + resultTo);
4558 if (!sourceRecord.info.packageName.equals("android")) {
4559 throw new SecurityException(
4560 "Must be called from an activity that is declared in the android package");
4562 if (sourceRecord.app == null) {
4563 throw new SecurityException("Called without a process attached to activity");
4565 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4566 // This is still okay, as long as this activity is running under the
4567 // uid of the original calling activity.
4568 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4569 throw new SecurityException(
4570 "Calling activity in uid " + sourceRecord.app.uid
4571 + " must be system uid or original calling uid "
4572 + sourceRecord.launchedFromUid);
4575 if (ignoreTargetSecurity) {
4576 if (intent.getComponent() == null) {
4577 throw new SecurityException(
4578 "Component must be specified with ignoreTargetSecurity");
4580 if (intent.getSelector() != null) {
4581 throw new SecurityException(
4582 "Selector not allowed with ignoreTargetSecurity");
4585 targetUid = sourceRecord.launchedFromUid;
4586 targetPackage = sourceRecord.launchedFromPackage;
4589 if (userId == UserHandle.USER_NULL) {
4590 userId = UserHandle.getUserId(sourceRecord.app.uid);
4593 // TODO: Switch to user app stacks here.
4595 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4596 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4597 null, null, bOptions, ignoreTargetSecurity, userId, null,
4598 "startActivityAsCaller");
4600 } catch (SecurityException e) {
4601 // XXX need to figure out how to propagate to original app.
4602 // A SecurityException here is generally actually a fault of the original
4603 // calling activity (such as a fairly granting permissions), so propagate it
4606 StringBuilder msg = new StringBuilder();
4607 msg.append("While launching");
4608 msg.append(intent.toString());
4610 msg.append(e.getMessage());
4617 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4618 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4619 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4620 enforceNotIsolatedCaller("startActivityAndWait");
4621 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4622 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4623 WaitResult res = new WaitResult();
4624 // TODO: Switch to user app stacks here.
4625 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4626 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4627 bOptions, false, userId, null, "startActivityAndWait");
4632 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4633 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4634 int startFlags, Configuration config, Bundle bOptions, int userId) {
4635 enforceNotIsolatedCaller("startActivityWithConfig");
4636 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4637 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4638 // TODO: Switch to user app stacks here.
4639 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4640 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4641 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4646 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4647 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4648 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4649 throws TransactionTooLargeException {
4650 enforceNotIsolatedCaller("startActivityIntentSender");
4651 // Refuse possible leaked file descriptors
4652 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4653 throw new IllegalArgumentException("File descriptors passed in Intent");
4656 if (!(target instanceof PendingIntentRecord)) {
4657 throw new IllegalArgumentException("Bad PendingIntent object");
4660 PendingIntentRecord pir = (PendingIntentRecord)target;
4662 synchronized (this) {
4663 // If this is coming from the currently resumed activity, it is
4664 // effectively saying that app switches are allowed at this point.
4665 final ActivityStack stack = getFocusedStack();
4666 if (stack.mResumedActivity != null &&
4667 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4668 mAppSwitchesAllowedTime = 0;
4671 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4672 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4677 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4678 Intent intent, String resolvedType, IVoiceInteractionSession session,
4679 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4680 Bundle bOptions, int userId) {
4681 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4682 != PackageManager.PERMISSION_GRANTED) {
4683 String msg = "Permission Denial: startVoiceActivity() from pid="
4684 + Binder.getCallingPid()
4685 + ", uid=" + Binder.getCallingUid()
4686 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4688 throw new SecurityException(msg);
4690 if (session == null || interactor == null) {
4691 throw new NullPointerException("null session or interactor");
4693 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4694 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4695 // TODO: Switch to user app stacks here.
4696 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4697 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4698 null, bOptions, false, userId, null, "startVoiceActivity");
4702 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4703 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4704 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4705 != PackageManager.PERMISSION_GRANTED) {
4706 final String msg = "Permission Denial: startAssistantActivity() from pid="
4707 + Binder.getCallingPid()
4708 + ", uid=" + Binder.getCallingUid()
4709 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4711 throw new SecurityException(msg);
4713 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4714 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4715 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4716 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4717 userId, null, "startAssistantActivity");
4721 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4722 throws RemoteException {
4723 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4724 synchronized (this) {
4725 ActivityRecord activity = getFocusedStack().topActivity();
4726 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4727 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4729 if (mRunningVoice != null || activity.getTask().voiceSession != null
4730 || activity.voiceSession != null) {
4731 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4734 if (activity.pendingVoiceInteractionStart) {
4735 Slog.w(TAG, "Pending start of voice interaction already.");
4738 activity.pendingVoiceInteractionStart = true;
4740 LocalServices.getService(VoiceInteractionManagerInternal.class)
4741 .startLocalVoiceInteraction(callingActivity, options);
4745 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4746 LocalServices.getService(VoiceInteractionManagerInternal.class)
4747 .stopLocalVoiceInteraction(callingActivity);
4751 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4752 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4753 .supportsLocalVoiceInteraction();
4756 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4757 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4758 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4759 if (activityToCallback == null) return;
4760 activityToCallback.setVoiceSessionLocked(voiceSession);
4762 // Inform the activity
4764 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4766 long token = Binder.clearCallingIdentity();
4768 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4770 Binder.restoreCallingIdentity(token);
4772 // TODO: VI Should we cache the activity so that it's easier to find later
4773 // rather than scan through all the stacks and activities?
4774 } catch (RemoteException re) {
4775 activityToCallback.clearVoiceSessionLocked();
4776 // TODO: VI Should this terminate the voice session?
4781 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4782 synchronized (this) {
4783 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4785 mVoiceWakeLock.acquire();
4787 mVoiceWakeLock.release();
4794 public boolean startNextMatchingActivity(IBinder callingActivity,
4795 Intent intent, Bundle bOptions) {
4796 // Refuse possible leaked file descriptors
4797 if (intent != null && intent.hasFileDescriptors() == true) {
4798 throw new IllegalArgumentException("File descriptors passed in Intent");
4800 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4802 synchronized (this) {
4803 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4805 ActivityOptions.abort(options);
4808 if (r.app == null || r.app.thread == null) {
4809 // The caller is not running... d'oh!
4810 ActivityOptions.abort(options);
4813 intent = new Intent(intent);
4814 // The caller is not allowed to change the data.
4815 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4816 // And we are resetting to find the next component...
4817 intent.setComponent(null);
4819 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4821 ActivityInfo aInfo = null;
4823 List<ResolveInfo> resolves =
4824 AppGlobals.getPackageManager().queryIntentActivities(
4825 intent, r.resolvedType,
4826 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4827 UserHandle.getCallingUserId()).getList();
4829 // Look for the original activity in the list...
4830 final int N = resolves != null ? resolves.size() : 0;
4831 for (int i=0; i<N; i++) {
4832 ResolveInfo rInfo = resolves.get(i);
4833 if (rInfo.activityInfo.packageName.equals(r.packageName)
4834 && rInfo.activityInfo.name.equals(r.info.name)) {
4835 // We found the current one... the next matching is
4839 aInfo = resolves.get(i).activityInfo;
4842 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4843 + "/" + r.info.name);
4844 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4845 ? "null" : aInfo.packageName + "/" + aInfo.name));
4850 } catch (RemoteException e) {
4853 if (aInfo == null) {
4854 // Nobody who is next!
4855 ActivityOptions.abort(options);
4856 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4860 intent.setComponent(new ComponentName(
4861 aInfo.applicationInfo.packageName, aInfo.name));
4862 intent.setFlags(intent.getFlags()&~(
4863 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4864 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4865 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4866 Intent.FLAG_ACTIVITY_NEW_TASK));
4868 // Okay now we need to start the new activity, replacing the
4869 // currently running activity. This is a little tricky because
4870 // we want to start the new one as if the current one is finished,
4871 // but not finish the current one first so that there is no flicker.
4873 final boolean wasFinishing = r.finishing;
4876 // Propagate reply information over to the new activity.
4877 final ActivityRecord resultTo = r.resultTo;
4878 final String resultWho = r.resultWho;
4879 final int requestCode = r.requestCode;
4881 if (resultTo != null) {
4882 resultTo.removeResultsLocked(r, resultWho, requestCode);
4885 final long origId = Binder.clearCallingIdentity();
4886 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4887 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4888 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4889 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4890 false, false, null, null, "startNextMatchingActivity");
4891 Binder.restoreCallingIdentity(origId);
4893 r.finishing = wasFinishing;
4894 if (res != ActivityManager.START_SUCCESS) {
4902 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4903 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4904 String msg = "Permission Denial: startActivityFromRecents called without " +
4905 START_TASKS_FROM_RECENTS;
4907 throw new SecurityException(msg);
4909 final long origId = Binder.clearCallingIdentity();
4911 synchronized (this) {
4912 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4915 Binder.restoreCallingIdentity(origId);
4919 final int startActivityInPackage(int uid, String callingPackage,
4920 Intent intent, String resolvedType, IBinder resultTo,
4921 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4922 TaskRecord inTask, String reason) {
4924 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4925 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4927 // TODO: Switch to user app stacks here.
4928 return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4929 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4930 null, null, null, bOptions, false, userId, inTask, reason);
4934 public final int startActivities(IApplicationThread caller, String callingPackage,
4935 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4937 final String reason = "startActivities";
4938 enforceNotIsolatedCaller(reason);
4939 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4940 userId, false, ALLOW_FULL_ONLY, reason, null);
4941 // TODO: Switch to user app stacks here.
4942 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4943 resolvedTypes, resultTo, bOptions, userId, reason);
4947 final int startActivitiesInPackage(int uid, String callingPackage,
4948 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4949 Bundle bOptions, int userId) {
4951 final String reason = "startActivityInPackage";
4952 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4953 userId, false, ALLOW_FULL_ONLY, reason, null);
4954 // TODO: Switch to user app stacks here.
4955 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4956 resultTo, bOptions, userId, reason);
4961 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4962 synchronized (this) {
4963 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4967 r.reportFullyDrawnLocked(restoredFromBundle);
4972 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4973 synchronized (this) {
4974 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4978 final long origId = Binder.clearCallingIdentity();
4980 r.setRequestedOrientation(requestedOrientation);
4982 Binder.restoreCallingIdentity(origId);
4988 public int getRequestedOrientation(IBinder token) {
4989 synchronized (this) {
4990 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4992 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4994 return r.getRequestedOrientation();
4999 public final void requestActivityRelaunch(IBinder token) {
5000 synchronized(this) {
5001 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5005 final long origId = Binder.clearCallingIdentity();
5007 r.forceNewConfig = true;
5008 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5009 true /* preserveWindow */);
5011 Binder.restoreCallingIdentity(origId);
5017 * This is the internal entry point for handling Activity.finish().
5019 * @param token The Binder token referencing the Activity we want to finish.
5020 * @param resultCode Result code, if any, from this Activity.
5021 * @param resultData Result data (Intent), if any, from this Activity.
5022 * @param finishTask Whether to finish the task associated with this Activity.
5024 * @return Returns true if the activity successfully finished, or false if it is still running.
5027 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5029 // Refuse possible leaked file descriptors
5030 if (resultData != null && resultData.hasFileDescriptors() == true) {
5031 throw new IllegalArgumentException("File descriptors passed in Intent");
5034 synchronized(this) {
5035 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5039 // Keep track of the root activity of the task before we finish it
5040 TaskRecord tr = r.getTask();
5041 ActivityRecord rootR = tr.getRootActivity();
5042 if (rootR == null) {
5043 Slog.w(TAG, "Finishing task with all activities already finished");
5045 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5047 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5048 mStackSupervisor.isLastLockedTask(tr)) {
5049 Slog.i(TAG, "Not finishing task in lock task mode");
5050 mStackSupervisor.showLockTaskToast();
5053 if (mController != null) {
5054 // Find the first activity that is not finishing.
5055 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5057 // ask watcher if this is allowed
5058 boolean resumeOK = true;
5060 resumeOK = mController.activityResuming(next.packageName);
5061 } catch (RemoteException e) {
5063 Watchdog.getInstance().setActivityController(null);
5067 Slog.i(TAG, "Not finishing activity because controller resumed");
5072 final long origId = Binder.clearCallingIdentity();
5075 final boolean finishWithRootActivity =
5076 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5077 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5078 || (finishWithRootActivity && r == rootR)) {
5079 // If requested, remove the task that is associated to this activity only if it
5080 // was the root activity in the task. The result code and data is ignored
5081 // because we don't support returning them across task boundaries. Also, to
5082 // keep backwards compatibility we remove the task from recents when finishing
5083 // task with root activity.
5084 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5086 Slog.i(TAG, "Removing task failed to finish activity");
5089 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5090 resultData, "app-request", true);
5092 Slog.i(TAG, "Failed to finish by app-request");
5097 Binder.restoreCallingIdentity(origId);
5103 public final void finishHeavyWeightApp() {
5104 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5105 != PackageManager.PERMISSION_GRANTED) {
5106 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5107 + Binder.getCallingPid()
5108 + ", uid=" + Binder.getCallingUid()
5109 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5111 throw new SecurityException(msg);
5114 synchronized(this) {
5115 if (mHeavyWeightProcess == null) {
5119 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5120 for (int i = 0; i < activities.size(); i++) {
5121 ActivityRecord r = activities.get(i);
5122 if (!r.finishing && r.isInStackLocked()) {
5123 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5124 null, "finish-heavy", true);
5128 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5129 mHeavyWeightProcess.userId, 0));
5130 mHeavyWeightProcess = null;
5135 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5137 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5138 != PackageManager.PERMISSION_GRANTED) {
5139 String msg = "Permission Denial: crashApplication() from pid="
5140 + Binder.getCallingPid()
5141 + ", uid=" + Binder.getCallingUid()
5142 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5144 throw new SecurityException(msg);
5147 synchronized(this) {
5148 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5153 public final void finishSubActivity(IBinder token, String resultWho,
5155 synchronized(this) {
5156 final long origId = Binder.clearCallingIdentity();
5157 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5159 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5161 Binder.restoreCallingIdentity(origId);
5166 public boolean finishActivityAffinity(IBinder token) {
5167 synchronized(this) {
5168 final long origId = Binder.clearCallingIdentity();
5170 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5175 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5177 final TaskRecord task = r.getTask();
5178 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5179 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5180 mStackSupervisor.showLockTaskToast();
5183 return task.getStack().finishActivityAffinityLocked(r);
5185 Binder.restoreCallingIdentity(origId);
5191 public void finishVoiceTask(IVoiceInteractionSession session) {
5192 synchronized (this) {
5193 final long origId = Binder.clearCallingIdentity();
5195 // TODO: VI Consider treating local voice interactions and voice tasks
5197 mStackSupervisor.finishVoiceTask(session);
5199 Binder.restoreCallingIdentity(origId);
5206 public boolean releaseActivityInstance(IBinder token) {
5207 synchronized(this) {
5208 final long origId = Binder.clearCallingIdentity();
5210 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5214 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5216 Binder.restoreCallingIdentity(origId);
5222 public void releaseSomeActivities(IApplicationThread appInt) {
5223 synchronized(this) {
5224 final long origId = Binder.clearCallingIdentity();
5226 ProcessRecord app = getRecordForAppLocked(appInt);
5227 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5229 Binder.restoreCallingIdentity(origId);
5235 public boolean willActivityBeVisible(IBinder token) {
5236 synchronized(this) {
5237 ActivityStack stack = ActivityRecord.getStackLocked(token);
5238 if (stack != null) {
5239 return stack.willActivityBeVisibleLocked(token);
5246 public void overridePendingTransition(IBinder token, String packageName,
5247 int enterAnim, int exitAnim) {
5248 synchronized(this) {
5249 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5254 final long origId = Binder.clearCallingIdentity();
5256 if (self.state == ActivityState.RESUMED
5257 || self.state == ActivityState.PAUSING) {
5258 mWindowManager.overridePendingAppTransition(packageName,
5259 enterAnim, exitAnim, null);
5262 Binder.restoreCallingIdentity(origId);
5267 * Main function for removing an existing process from the activity manager
5268 * as a result of that process going away. Clears out all connections
5271 private final void handleAppDiedLocked(ProcessRecord app,
5272 boolean restarting, boolean allowRestart) {
5274 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5275 false /*replacingPid*/);
5276 if (!kept && !restarting) {
5277 removeLruProcessLocked(app);
5279 ProcessList.remove(pid);
5283 if (mProfileProc == app) {
5284 clearProfilerLocked();
5287 // Remove this application's activities from active lists.
5288 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5290 app.activities.clear();
5292 if (app.instr != null) {
5293 Slog.w(TAG, "Crash of app " + app.processName
5294 + " running instrumentation " + app.instr.mClass);
5295 Bundle info = new Bundle();
5296 info.putString("shortMsg", "Process crashed.");
5297 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5300 mWindowManager.deferSurfaceLayout();
5302 if (!restarting && hasVisibleActivities
5303 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5304 // If there was nothing to resume, and we are not already restarting this process, but
5305 // there is a visible activity that is hosted by the process... then make sure all
5306 // visible activities are running, taking care of restarting this process.
5307 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5310 mWindowManager.continueSurfaceLayout();
5314 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5315 final IBinder threadBinder = thread.asBinder();
5316 // Find the application record.
5317 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5318 final ProcessRecord rec = mLruProcesses.get(i);
5319 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5326 final ProcessRecord getRecordForAppLocked(
5327 IApplicationThread thread) {
5328 if (thread == null) {
5332 int appIndex = getLRURecordIndexForAppLocked(thread);
5333 if (appIndex >= 0) {
5334 return mLruProcesses.get(appIndex);
5337 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5338 // double-check that.
5339 final IBinder threadBinder = thread.asBinder();
5340 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5341 for (int i = pmap.size()-1; i >= 0; i--) {
5342 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5343 for (int j = procs.size()-1; j >= 0; j--) {
5344 final ProcessRecord proc = procs.valueAt(j);
5345 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5346 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5356 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5357 // If there are no longer any background processes running,
5358 // and the app that died was not running instrumentation,
5359 // then tell everyone we are now low on memory.
5360 boolean haveBg = false;
5361 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5362 ProcessRecord rec = mLruProcesses.get(i);
5363 if (rec.thread != null
5364 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5371 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5373 long now = SystemClock.uptimeMillis();
5374 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5377 mLastMemUsageReportTime = now;
5380 final ArrayList<ProcessMemInfo> memInfos
5381 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5382 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5383 long now = SystemClock.uptimeMillis();
5384 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5385 ProcessRecord rec = mLruProcesses.get(i);
5386 if (rec == dyingProc || rec.thread == null) {
5390 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5391 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5393 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5394 // The low memory report is overriding any current
5395 // state for a GC request. Make sure to do
5396 // heavy/important/visible/foreground processes first.
5397 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5398 rec.lastRequestedGc = 0;
5400 rec.lastRequestedGc = rec.lastLowMemory;
5402 rec.reportLowMemory = true;
5403 rec.lastLowMemory = now;
5404 mProcessesToGc.remove(rec);
5405 addProcessToGcListLocked(rec);
5409 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5410 mHandler.sendMessage(msg);
5412 scheduleAppGcsLocked();
5416 final void appDiedLocked(ProcessRecord app) {
5417 appDiedLocked(app, app.pid, app.thread, false);
5420 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5421 boolean fromBinderDied) {
5422 // First check if this ProcessRecord is actually active for the pid.
5423 synchronized (mPidsSelfLocked) {
5424 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5425 if (curProc != app) {
5426 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5431 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5432 synchronized (stats) {
5433 stats.noteProcessDiedLocked(app.info.uid, pid);
5437 if (!fromBinderDied) {
5438 killProcessQuiet(pid);
5440 killProcessGroup(app.uid, pid);
5444 // Clean up already done if the process has been re-started.
5445 if (app.pid == pid && app.thread != null &&
5446 app.thread.asBinder() == thread.asBinder()) {
5447 boolean doLowMem = app.instr == null;
5448 boolean doOomAdj = doLowMem;
5449 if (!app.killedByAm) {
5450 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5451 + ProcessList.makeOomAdjString(app.setAdj)
5452 + ProcessList.makeProcStateString(app.setProcState));
5453 mAllowLowerMemLevel = true;
5455 // Note that we always want to do oom adj to update our state with the
5456 // new number of procs.
5457 mAllowLowerMemLevel = false;
5460 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5461 app.setAdj, app.setProcState);
5462 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5463 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5464 handleAppDiedLocked(app, false, true);
5467 updateOomAdjLocked();
5470 doLowMemReportIfNeededLocked(app);
5472 } else if (app.pid != pid) {
5473 // A new process has already been started.
5474 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5475 + ") has died and restarted (pid " + app.pid + ").");
5476 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5477 } else if (DEBUG_PROCESSES) {
5478 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5479 + thread.asBinder());
5484 * If a stack trace dump file is configured, dump process stack traces.
5485 * @param clearTraces causes the dump file to be erased prior to the new
5486 * traces being written, if true; when false, the new traces will be
5487 * appended to any existing file content.
5488 * @param firstPids of dalvik VM processes to dump stack traces for first
5489 * @param lastPids of dalvik VM processes to dump stack traces for last
5490 * @param nativePids optional list of native pids to dump stack crawls
5492 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5493 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5494 ArrayList<Integer> nativePids) {
5495 ArrayList<Integer> extraPids = null;
5497 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5498 // of the top users at the time of the request.
5499 if (processCpuTracker != null) {
5500 processCpuTracker.init();
5503 } catch (InterruptedException ignored) {
5506 processCpuTracker.update();
5508 // We'll take the stack crawls of just the top apps using CPU.
5509 final int N = processCpuTracker.countWorkingStats();
5510 extraPids = new ArrayList<>();
5511 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5512 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5513 if (lastPids.indexOfKey(stats.pid) >= 0) {
5514 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5516 extraPids.add(stats.pid);
5517 } else if (DEBUG_ANR) {
5518 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5524 boolean useTombstonedForJavaTraces = false;
5527 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5528 if (tracesDirProp.isEmpty()) {
5529 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5530 // dumping scheme. All traces are written to a global trace file (usually
5531 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5532 // the file if requested.
5534 // This mode of operation will be removed in the near future.
5537 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5538 if (globalTracesPath.isEmpty()) {
5539 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5543 tracesFile = new File(globalTracesPath);
5545 if (clearTraces && tracesFile.exists()) {
5546 tracesFile.delete();
5549 tracesFile.createNewFile();
5550 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5551 } catch (IOException e) {
5552 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5556 File tracesDir = new File(tracesDirProp);
5557 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5558 // Each set of ANR traces is written to a separate file and dumpstate will process
5559 // all such files and add them to a captured bug report if they're recent enough.
5560 maybePruneOldTraces(tracesDir);
5562 // NOTE: We should consider creating the file in native code atomically once we've
5563 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5565 tracesFile = createAnrDumpFile(tracesDir);
5566 if (tracesFile == null) {
5570 useTombstonedForJavaTraces = true;
5573 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5574 useTombstonedForJavaTraces);
5578 @GuardedBy("ActivityManagerService.class")
5579 private static SimpleDateFormat sAnrFileDateFormat;
5581 private static synchronized File createAnrDumpFile(File tracesDir) {
5582 if (sAnrFileDateFormat == null) {
5583 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5586 final String formattedDate = sAnrFileDateFormat.format(new Date());
5587 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5590 if (anrFile.createNewFile()) {
5591 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5594 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5596 } catch (IOException ioe) {
5597 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5604 * Prune all trace files that are more than a day old.
5606 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5607 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5608 * since it's the system_server that creates trace files for most ANRs.
5610 private static void maybePruneOldTraces(File tracesDir) {
5611 final long now = System.currentTimeMillis();
5612 final File[] traceFiles = tracesDir.listFiles();
5614 if (traceFiles != null) {
5615 for (File file : traceFiles) {
5616 if ((now - file.lastModified()) > DAY_IN_MILLIS) {
5617 if (!file.delete()) {
5618 Slog.w(TAG, "Unable to prune stale trace file: " + file);
5626 * Legacy code, do not use. Existing users will be deleted.
5631 public static class DumpStackFileObserver extends FileObserver {
5632 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5633 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5635 private final String mTracesPath;
5636 private boolean mClosed;
5638 public DumpStackFileObserver(String tracesPath) {
5639 super(tracesPath, FileObserver.CLOSE_WRITE);
5640 mTracesPath = tracesPath;
5644 public synchronized void onEvent(int event, String path) {
5649 public long dumpWithTimeout(int pid, long timeout) {
5650 sendSignal(pid, SIGNAL_QUIT);
5651 final long start = SystemClock.elapsedRealtime();
5653 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5654 synchronized (this) {
5656 wait(waitTime); // Wait for traces file to be closed.
5657 } catch (InterruptedException e) {
5662 // This avoids a corner case of passing a negative time to the native
5663 // trace in case we've already hit the overall timeout.
5664 final long timeWaited = SystemClock.elapsedRealtime() - start;
5665 if (timeWaited >= timeout) {
5670 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5671 ". Attempting native stack collection.");
5673 final long nativeDumpTimeoutMs = Math.min(
5674 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5676 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5677 (int) (nativeDumpTimeoutMs / 1000));
5680 final long end = SystemClock.elapsedRealtime();
5683 return (end - start);
5688 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5689 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5690 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5691 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5694 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5695 final long timeStart = SystemClock.elapsedRealtime();
5696 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5697 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5698 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5701 return SystemClock.elapsedRealtime() - timeStart;
5704 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5705 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5706 boolean useTombstonedForJavaTraces) {
5708 // We don't need any sort of inotify based monitoring when we're dumping traces via
5709 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5710 // control of all writes to the file in question.
5711 final DumpStackFileObserver observer;
5712 if (useTombstonedForJavaTraces) {
5715 // Use a FileObserver to detect when traces finish writing.
5716 // The order of traces is considered important to maintain for legibility.
5717 observer = new DumpStackFileObserver(tracesFile);
5720 // We must complete all stack dumps within 20 seconds.
5721 long remainingTime = 20 * 1000;
5723 if (observer != null) {
5724 observer.startWatching();
5727 // First collect all of the stacks of the most important pids.
5728 if (firstPids != null) {
5729 int num = firstPids.size();
5730 for (int i = 0; i < num; i++) {
5731 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5732 + firstPids.get(i));
5733 final long timeTaken;
5734 if (useTombstonedForJavaTraces) {
5735 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5737 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5740 remainingTime -= timeTaken;
5741 if (remainingTime <= 0) {
5742 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5743 "); deadline exceeded.");
5748 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5753 // Next collect the stacks of the native pids
5754 if (nativePids != null) {
5755 for (int pid : nativePids) {
5756 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5757 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5759 final long start = SystemClock.elapsedRealtime();
5760 Debug.dumpNativeBacktraceToFileTimeout(
5761 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5762 final long timeTaken = SystemClock.elapsedRealtime() - start;
5764 remainingTime -= timeTaken;
5765 if (remainingTime <= 0) {
5766 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5767 "); deadline exceeded.");
5772 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5777 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5778 if (extraPids != null) {
5779 for (int pid : extraPids) {
5780 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5782 final long timeTaken;
5783 if (useTombstonedForJavaTraces) {
5784 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5786 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5789 remainingTime -= timeTaken;
5790 if (remainingTime <= 0) {
5791 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5792 "); deadline exceeded.");
5797 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5802 if (observer != null) {
5803 observer.stopWatching();
5808 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5809 if (true || Build.IS_USER) {
5812 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5813 if (tracesPath == null || tracesPath.length() == 0) {
5817 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5818 StrictMode.allowThreadDiskWrites();
5820 final File tracesFile = new File(tracesPath);
5821 final File tracesDir = tracesFile.getParentFile();
5822 final File tracesTmp = new File(tracesDir, "__tmp__");
5824 if (tracesFile.exists()) {
5826 tracesFile.renameTo(tracesTmp);
5828 StringBuilder sb = new StringBuilder();
5829 Time tobj = new Time();
5830 tobj.set(System.currentTimeMillis());
5831 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5833 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5834 sb.append(" since ");
5836 FileOutputStream fos = new FileOutputStream(tracesFile);
5837 fos.write(sb.toString().getBytes());
5839 fos.write("\n*** No application process!".getBytes());
5842 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5843 } catch (IOException e) {
5844 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5849 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5850 firstPids.add(app.pid);
5851 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5854 File lastTracesFile = null;
5855 File curTracesFile = null;
5856 for (int i=9; i>=0; i--) {
5857 String name = String.format(Locale.US, "slow%02d.txt", i);
5858 curTracesFile = new File(tracesDir, name);
5859 if (curTracesFile.exists()) {
5860 if (lastTracesFile != null) {
5861 curTracesFile.renameTo(lastTracesFile);
5863 curTracesFile.delete();
5866 lastTracesFile = curTracesFile;
5868 tracesFile.renameTo(curTracesFile);
5869 if (tracesTmp.exists()) {
5870 tracesTmp.renameTo(tracesFile);
5873 StrictMode.setThreadPolicy(oldPolicy);
5877 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5878 if (!mLaunchWarningShown) {
5879 mLaunchWarningShown = true;
5880 mUiHandler.post(new Runnable() {
5883 synchronized (ActivityManagerService.this) {
5884 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5886 mUiHandler.postDelayed(new Runnable() {
5889 synchronized (ActivityManagerService.this) {
5891 mLaunchWarningShown = false;
5902 public boolean clearApplicationUserData(final String packageName,
5903 final IPackageDataObserver observer, int userId) {
5904 enforceNotIsolatedCaller("clearApplicationUserData");
5905 int uid = Binder.getCallingUid();
5906 int pid = Binder.getCallingPid();
5907 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5908 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5910 final ApplicationInfo appInfo;
5911 final boolean isInstantApp;
5913 long callingId = Binder.clearCallingIdentity();
5915 IPackageManager pm = AppGlobals.getPackageManager();
5916 synchronized(this) {
5917 // Instant packages are not protected
5918 if (getPackageManagerInternalLocked().isPackageDataProtected(
5919 resolvedUserId, packageName)) {
5920 throw new SecurityException(
5921 "Cannot clear data for a protected package: " + packageName);
5924 ApplicationInfo applicationInfo = null;
5926 applicationInfo = pm.getApplicationInfo(packageName,
5927 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5928 } catch (RemoteException e) {
5931 appInfo = applicationInfo;
5933 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5935 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5936 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5937 throw new SecurityException("PID " + pid + " does not have permission "
5938 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5939 + " of package " + packageName);
5942 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5943 .hasInstantApplicationMetadata(packageName, resolvedUserId);
5944 final boolean isUninstalledAppWithoutInstantMetadata =
5945 (appInfo == null && !hasInstantMetadata);
5946 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5947 || hasInstantMetadata;
5948 final boolean canAccessInstantApps = checkComponentPermission(
5949 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5950 == PackageManager.PERMISSION_GRANTED;
5952 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5953 && !canAccessInstantApps)) {
5954 Slog.w(TAG, "Invalid packageName: " + packageName);
5955 if (observer != null) {
5957 observer.onRemoveCompleted(packageName, false);
5958 } catch (RemoteException e) {
5959 Slog.i(TAG, "Observer no longer exists.");
5965 if (appInfo != null) {
5966 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5967 // Remove all tasks match the cleared application package and user
5968 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5969 final TaskRecord tr = mRecentTasks.get(i);
5970 final String taskPackageName =
5971 tr.getBaseIntent().getComponent().getPackageName();
5972 if (tr.userId != resolvedUserId) continue;
5973 if (!taskPackageName.equals(packageName)) continue;
5974 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5975 REMOVE_FROM_RECENTS);
5980 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5982 public void onRemoveCompleted(String packageName, boolean succeeded)
5983 throws RemoteException {
5984 if (appInfo != null) {
5985 synchronized (ActivityManagerService.this) {
5986 finishForceStopPackageLocked(packageName, appInfo.uid);
5989 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5990 Uri.fromParts("package", packageName, null));
5991 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5992 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5993 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5995 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5996 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5997 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6000 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6001 null, null, null, null, false, false, resolvedUserId);
6004 if (observer != null) {
6005 observer.onRemoveCompleted(packageName, succeeded);
6011 // Clear application user data
6012 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6014 if (appInfo != null) {
6015 synchronized (this) {
6016 // Remove all permissions granted from/to this package
6017 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6020 // Reset notification settings.
6021 INotificationManager inm = NotificationManager.getService();
6022 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6024 } catch (RemoteException e) {
6027 Binder.restoreCallingIdentity(callingId);
6033 public void killBackgroundProcesses(final String packageName, int userId) {
6034 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6035 != PackageManager.PERMISSION_GRANTED &&
6036 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6037 != PackageManager.PERMISSION_GRANTED) {
6038 String msg = "Permission Denial: killBackgroundProcesses() from pid="
6039 + Binder.getCallingPid()
6040 + ", uid=" + Binder.getCallingUid()
6041 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6043 throw new SecurityException(msg);
6046 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6047 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6048 long callingId = Binder.clearCallingIdentity();
6050 IPackageManager pm = AppGlobals.getPackageManager();
6051 synchronized(this) {
6054 appId = UserHandle.getAppId(
6055 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6056 } catch (RemoteException e) {
6059 Slog.w(TAG, "Invalid packageName: " + packageName);
6062 killPackageProcessesLocked(packageName, appId, userId,
6063 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6066 Binder.restoreCallingIdentity(callingId);
6071 public void killAllBackgroundProcesses() {
6072 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6073 != PackageManager.PERMISSION_GRANTED) {
6074 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6075 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6076 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6078 throw new SecurityException(msg);
6081 final long callingId = Binder.clearCallingIdentity();
6083 synchronized (this) {
6084 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6085 final int NP = mProcessNames.getMap().size();
6086 for (int ip = 0; ip < NP; ip++) {
6087 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6088 final int NA = apps.size();
6089 for (int ia = 0; ia < NA; ia++) {
6090 final ProcessRecord app = apps.valueAt(ia);
6091 if (app.persistent) {
6092 // We don't kill persistent processes.
6097 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6104 final int N = procs.size();
6105 for (int i = 0; i < N; i++) {
6106 removeProcessLocked(procs.get(i), false, true, "kill all background");
6109 mAllowLowerMemLevel = true;
6111 updateOomAdjLocked();
6112 doLowMemReportIfNeededLocked(null);
6115 Binder.restoreCallingIdentity(callingId);
6120 * Kills all background processes, except those matching any of the
6121 * specified properties.
6123 * @param minTargetSdk the target SDK version at or above which to preserve
6124 * processes, or {@code -1} to ignore the target SDK
6125 * @param maxProcState the process state at or below which to preserve
6126 * processes, or {@code -1} to ignore the process state
6128 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6129 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6130 != PackageManager.PERMISSION_GRANTED) {
6131 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6132 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6133 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6135 throw new SecurityException(msg);
6138 final long callingId = Binder.clearCallingIdentity();
6140 synchronized (this) {
6141 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6142 final int NP = mProcessNames.getMap().size();
6143 for (int ip = 0; ip < NP; ip++) {
6144 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6145 final int NA = apps.size();
6146 for (int ia = 0; ia < NA; ia++) {
6147 final ProcessRecord app = apps.valueAt(ia);
6150 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6151 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6158 final int N = procs.size();
6159 for (int i = 0; i < N; i++) {
6160 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6164 Binder.restoreCallingIdentity(callingId);
6169 public void forceStopPackage(final String packageName, int userId) {
6170 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6171 != PackageManager.PERMISSION_GRANTED) {
6172 String msg = "Permission Denial: forceStopPackage() from pid="
6173 + Binder.getCallingPid()
6174 + ", uid=" + Binder.getCallingUid()
6175 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6177 throw new SecurityException(msg);
6179 final int callingPid = Binder.getCallingPid();
6180 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6181 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6182 long callingId = Binder.clearCallingIdentity();
6184 IPackageManager pm = AppGlobals.getPackageManager();
6185 synchronized(this) {
6186 int[] users = userId == UserHandle.USER_ALL
6187 ? mUserController.getUsers() : new int[] { userId };
6188 for (int user : users) {
6191 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6193 } catch (RemoteException e) {
6196 Slog.w(TAG, "Invalid packageName: " + packageName);
6200 pm.setPackageStoppedState(packageName, true, user);
6201 } catch (RemoteException e) {
6202 } catch (IllegalArgumentException e) {
6203 Slog.w(TAG, "Failed trying to unstop package "
6204 + packageName + ": " + e);
6206 if (mUserController.isUserRunningLocked(user, 0)) {
6207 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6208 finishForceStopPackageLocked(packageName, pkgUid);
6213 Binder.restoreCallingIdentity(callingId);
6218 public void addPackageDependency(String packageName) {
6219 synchronized (this) {
6220 int callingPid = Binder.getCallingPid();
6221 if (callingPid == myPid()) {
6226 synchronized (mPidsSelfLocked) {
6227 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6230 if (proc.pkgDeps == null) {
6231 proc.pkgDeps = new ArraySet<String>(1);
6233 proc.pkgDeps.add(packageName);
6239 * The pkg name and app id have to be specified.
6242 public void killApplication(String pkg, int appId, int userId, String reason) {
6246 // Make sure the uid is valid.
6248 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6251 int callerUid = Binder.getCallingUid();
6252 // Only the system server can kill an application
6253 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6254 // Post an aysnc message to kill the application
6255 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6258 Bundle bundle = new Bundle();
6259 bundle.putString("pkg", pkg);
6260 bundle.putString("reason", reason);
6262 mHandler.sendMessage(msg);
6264 throw new SecurityException(callerUid + " cannot kill pkg: " +
6270 public void closeSystemDialogs(String reason) {
6271 enforceNotIsolatedCaller("closeSystemDialogs");
6273 final int pid = Binder.getCallingPid();
6274 final int uid = Binder.getCallingUid();
6275 final long origId = Binder.clearCallingIdentity();
6277 synchronized (this) {
6278 // Only allow this from foreground processes, so that background
6279 // applications can't abuse it to prevent system UI from being shown.
6280 if (uid >= FIRST_APPLICATION_UID) {
6282 synchronized (mPidsSelfLocked) {
6283 proc = mPidsSelfLocked.get(pid);
6285 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6286 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6287 + " from background process " + proc);
6291 closeSystemDialogsLocked(reason);
6294 Binder.restoreCallingIdentity(origId);
6298 void closeSystemDialogsLocked(String reason) {
6299 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6300 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6301 | Intent.FLAG_RECEIVER_FOREGROUND);
6302 if (reason != null) {
6303 intent.putExtra("reason", reason);
6305 mWindowManager.closeSystemDialogs(reason);
6307 mStackSupervisor.closeSystemDialogsLocked();
6309 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6310 AppOpsManager.OP_NONE, null, false, false,
6311 -1, SYSTEM_UID, UserHandle.USER_ALL);
6315 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6316 enforceNotIsolatedCaller("getProcessMemoryInfo");
6317 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6318 for (int i=pids.length-1; i>=0; i--) {
6321 synchronized (this) {
6322 synchronized (mPidsSelfLocked) {
6323 proc = mPidsSelfLocked.get(pids[i]);
6324 oomAdj = proc != null ? proc.setAdj : 0;
6327 infos[i] = new Debug.MemoryInfo();
6328 Debug.getMemoryInfo(pids[i], infos[i]);
6330 synchronized (this) {
6331 if (proc.thread != null && proc.setAdj == oomAdj) {
6332 // Record this for posterity if the process has been stable.
6333 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6334 infos[i].getTotalUss(), false, proc.pkgList);
6343 public long[] getProcessPss(int[] pids) {
6344 enforceNotIsolatedCaller("getProcessPss");
6345 long[] pss = new long[pids.length];
6346 for (int i=pids.length-1; i>=0; i--) {
6349 synchronized (this) {
6350 synchronized (mPidsSelfLocked) {
6351 proc = mPidsSelfLocked.get(pids[i]);
6352 oomAdj = proc != null ? proc.setAdj : 0;
6355 long[] tmpUss = new long[1];
6356 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6358 synchronized (this) {
6359 if (proc.thread != null && proc.setAdj == oomAdj) {
6360 // Record this for posterity if the process has been stable.
6361 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6370 public void killApplicationProcess(String processName, int uid) {
6371 if (processName == null) {
6375 int callerUid = Binder.getCallingUid();
6376 // Only the system server can kill an application
6377 if (callerUid == SYSTEM_UID) {
6378 synchronized (this) {
6379 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6380 if (app != null && app.thread != null) {
6382 app.thread.scheduleSuicide();
6383 } catch (RemoteException e) {
6384 // If the other end already died, then our work here is done.
6387 Slog.w(TAG, "Process/uid not found attempting kill of "
6388 + processName + " / " + uid);
6392 throw new SecurityException(callerUid + " cannot kill app process: " +
6397 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6398 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6399 false, true, false, false, UserHandle.getUserId(uid), reason);
6402 private void finishForceStopPackageLocked(final String packageName, int uid) {
6403 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6404 Uri.fromParts("package", packageName, null));
6405 if (!mProcessesReady) {
6406 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6407 | Intent.FLAG_RECEIVER_FOREGROUND);
6409 intent.putExtra(Intent.EXTRA_UID, uid);
6410 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6411 broadcastIntentLocked(null, null, intent,
6412 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6413 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6417 private final boolean killPackageProcessesLocked(String packageName, int appId,
6418 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6419 boolean doit, boolean evenPersistent, String reason) {
6420 ArrayList<ProcessRecord> procs = new ArrayList<>();
6422 // Remove all processes this package may have touched: all with the
6423 // same UID (except for the system or root user), and all whose name
6424 // matches the package name.
6425 final int NP = mProcessNames.getMap().size();
6426 for (int ip=0; ip<NP; ip++) {
6427 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6428 final int NA = apps.size();
6429 for (int ia=0; ia<NA; ia++) {
6430 ProcessRecord app = apps.valueAt(ia);
6431 if (app.persistent && !evenPersistent) {
6432 // we don't kill persistent processes
6442 // Skip process if it doesn't meet our oom adj requirement.
6443 if (app.setAdj < minOomAdj) {
6447 // If no package is specified, we call all processes under the
6449 if (packageName == null) {
6450 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6453 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6456 // Package has been specified, we want to hit all processes
6457 // that match it. We need to qualify this by the processes
6458 // that are running under the specified app and user ID.
6460 final boolean isDep = app.pkgDeps != null
6461 && app.pkgDeps.contains(packageName);
6462 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6465 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6468 if (!app.pkgList.containsKey(packageName) && !isDep) {
6473 // Process has passed all conditions, kill it!
6482 int N = procs.size();
6483 for (int i=0; i<N; i++) {
6484 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6486 updateOomAdjLocked();
6490 private void cleanupDisabledPackageComponentsLocked(
6491 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6493 Set<String> disabledClasses = null;
6494 boolean packageDisabled = false;
6495 IPackageManager pm = AppGlobals.getPackageManager();
6497 if (changedClasses == null) {
6498 // Nothing changed...
6502 // Determine enable/disable state of the package and its components.
6503 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6504 for (int i = changedClasses.length - 1; i >= 0; i--) {
6505 final String changedClass = changedClasses[i];
6507 if (changedClass.equals(packageName)) {
6509 // Entire package setting changed
6510 enabled = pm.getApplicationEnabledSetting(packageName,
6511 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6512 } catch (Exception e) {
6513 // No such package/component; probably racing with uninstall. In any
6514 // event it means we have nothing further to do here.
6517 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6518 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6519 if (packageDisabled) {
6520 // Entire package is disabled.
6521 // No need to continue to check component states.
6522 disabledClasses = null;
6527 enabled = pm.getComponentEnabledSetting(
6528 new ComponentName(packageName, changedClass),
6529 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6530 } catch (Exception e) {
6531 // As above, probably racing with uninstall.
6534 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6535 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6536 if (disabledClasses == null) {
6537 disabledClasses = new ArraySet<>(changedClasses.length);
6539 disabledClasses.add(changedClass);
6544 if (!packageDisabled && disabledClasses == null) {
6545 // Nothing to do here...
6549 // Clean-up disabled activities.
6550 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6551 packageName, disabledClasses, true, false, userId) && mBooted) {
6552 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6553 mStackSupervisor.scheduleIdleLocked();
6556 // Clean-up disabled tasks
6557 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6559 // Clean-up disabled services.
6560 mServices.bringDownDisabledPackageServicesLocked(
6561 packageName, disabledClasses, userId, false, killProcess, true);
6563 // Clean-up disabled providers.
6564 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6565 mProviderMap.collectPackageProvidersLocked(
6566 packageName, disabledClasses, true, false, userId, providers);
6567 for (int i = providers.size() - 1; i >= 0; i--) {
6568 removeDyingProviderLocked(null, providers.get(i), true);
6571 // Clean-up disabled broadcast receivers.
6572 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6573 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6574 packageName, disabledClasses, userId, true);
6579 final boolean clearBroadcastQueueForUserLocked(int userId) {
6580 boolean didSomething = false;
6581 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6582 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6583 null, null, userId, true);
6585 return didSomething;
6588 final boolean forceStopPackageLocked(String packageName, int appId,
6589 boolean callerWillRestart, boolean purgeCache, boolean doit,
6590 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6593 if (userId == UserHandle.USER_ALL && packageName == null) {
6594 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6597 if (appId < 0 && packageName != null) {
6599 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6600 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6601 } catch (RemoteException e) {
6606 if (packageName != null) {
6607 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6608 + " user=" + userId + ": " + reason);
6610 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6613 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6616 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6617 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6618 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6620 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6622 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6623 packageName, null, doit, evenPersistent, userId)) {
6627 didSomething = true;
6630 if (mServices.bringDownDisabledPackageServicesLocked(
6631 packageName, null, userId, evenPersistent, true, doit)) {
6635 didSomething = true;
6638 if (packageName == null) {
6639 // Remove all sticky broadcasts from this user.
6640 mStickyBroadcasts.remove(userId);
6643 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6644 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6645 userId, providers)) {
6649 didSomething = true;
6651 for (i = providers.size() - 1; i >= 0; i--) {
6652 removeDyingProviderLocked(null, providers.get(i), true);
6655 // Remove transient permissions granted from/to this package/user
6656 removeUriPermissionsForPackageLocked(packageName, userId, false);
6659 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6660 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6661 packageName, null, userId, doit);
6665 if (packageName == null || uninstalling) {
6666 // Remove pending intents. For now we only do this when force
6667 // stopping users, because we have some problems when doing this
6668 // for packages -- app widgets are not currently cleaned up for
6669 // such packages, so they can be left with bad pending intents.
6670 if (mIntentSenderRecords.size() > 0) {
6671 Iterator<WeakReference<PendingIntentRecord>> it
6672 = mIntentSenderRecords.values().iterator();
6673 while (it.hasNext()) {
6674 WeakReference<PendingIntentRecord> wpir = it.next();
6679 PendingIntentRecord pir = wpir.get();
6684 if (packageName == null) {
6685 // Stopping user, remove all objects for the user.
6686 if (pir.key.userId != userId) {
6687 // Not the same user, skip it.
6691 if (UserHandle.getAppId(pir.uid) != appId) {
6692 // Different app id, skip it.
6695 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6696 // Different user, skip it.
6699 if (!pir.key.packageName.equals(packageName)) {
6700 // Different package, skip it.
6707 didSomething = true;
6709 makeIntentSenderCanceledLocked(pir);
6710 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6711 pir.key.activity.pendingResults.remove(pir.ref);
6718 if (purgeCache && packageName != null) {
6719 AttributeCache ac = AttributeCache.instance();
6721 ac.removePackage(packageName);
6725 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6726 mStackSupervisor.scheduleIdleLocked();
6730 return didSomething;
6733 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6734 return removeProcessNameLocked(name, uid, null);
6737 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6738 final ProcessRecord expecting) {
6739 ProcessRecord old = mProcessNames.get(name, uid);
6740 // Only actually remove when the currently recorded value matches the
6741 // record that we expected; if it doesn't match then we raced with a
6742 // newly created process and we don't want to destroy the new one.
6743 if ((expecting == null) || (old == expecting)) {
6744 mProcessNames.remove(name, uid);
6746 if (old != null && old.uidRecord != null) {
6747 old.uidRecord.numProcs--;
6748 if (old.uidRecord.numProcs == 0) {
6749 // No more processes using this uid, tell clients it is gone.
6750 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6751 "No more processes in " + old.uidRecord);
6752 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6753 EventLogTags.writeAmUidStopped(uid);
6754 mActiveUids.remove(uid);
6755 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6757 old.uidRecord = null;
6759 mIsolatedProcesses.remove(uid);
6763 private final void addProcessNameLocked(ProcessRecord proc) {
6764 // We shouldn't already have a process under this name, but just in case we
6765 // need to clean up whatever may be there now.
6766 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6767 if (old == proc && proc.persistent) {
6768 // We are re-adding a persistent process. Whatevs! Just leave it there.
6769 Slog.w(TAG, "Re-adding persistent process " + proc);
6770 } else if (old != null) {
6771 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6773 UidRecord uidRec = mActiveUids.get(proc.uid);
6774 if (uidRec == null) {
6775 uidRec = new UidRecord(proc.uid);
6776 // This is the first appearance of the uid, report it now!
6777 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6778 "Creating new process uid: " + uidRec);
6779 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6780 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6781 uidRec.setWhitelist = uidRec.curWhitelist = true;
6783 uidRec.updateHasInternetPermission();
6784 mActiveUids.put(proc.uid, uidRec);
6785 EventLogTags.writeAmUidRunning(uidRec.uid);
6786 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6788 proc.uidRecord = uidRec;
6790 // Reset render thread tid if it was already set, so new process can set it again.
6791 proc.renderThreadTid = 0;
6793 mProcessNames.put(proc.processName, proc.uid, proc);
6794 if (proc.isolated) {
6795 mIsolatedProcesses.put(proc.uid, proc);
6799 boolean removeProcessLocked(ProcessRecord app,
6800 boolean callerWillRestart, boolean allowRestart, String reason) {
6801 final String name = app.processName;
6802 final int uid = app.uid;
6803 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6804 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6806 ProcessRecord old = mProcessNames.get(name, uid);
6808 // This process is no longer active, so nothing to do.
6809 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6812 removeProcessNameLocked(name, uid);
6813 if (mHeavyWeightProcess == app) {
6814 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6815 mHeavyWeightProcess.userId, 0));
6816 mHeavyWeightProcess = null;
6818 boolean needRestart = false;
6819 if (app.pid > 0 && app.pid != MY_PID) {
6821 synchronized (mPidsSelfLocked) {
6822 mPidsSelfLocked.remove(pid);
6823 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6825 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6826 boolean willRestart = false;
6827 if (app.persistent && !app.isolated) {
6828 if (!callerWillRestart) {
6834 app.kill(reason, true);
6836 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6837 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6839 handleAppDiedLocked(app, willRestart, allowRestart);
6841 removeLruProcessLocked(app);
6842 addAppLocked(app.info, null, false, null /* ABI override */);
6845 mRemovedProcesses.add(app);
6851 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6852 cleanupAppInLaunchingProvidersLocked(app, true);
6853 removeProcessLocked(app, false, true, "timeout publishing content providers");
6856 private final void processStartTimedOutLocked(ProcessRecord app) {
6857 final int pid = app.pid;
6858 boolean gone = false;
6859 synchronized (mPidsSelfLocked) {
6860 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6861 if (knownApp != null && knownApp.thread == null) {
6862 mPidsSelfLocked.remove(pid);
6868 Slog.w(TAG, "Process " + app + " failed to attach");
6869 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6870 pid, app.uid, app.processName);
6871 removeProcessNameLocked(app.processName, app.uid);
6872 if (mHeavyWeightProcess == app) {
6873 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6874 mHeavyWeightProcess.userId, 0));
6875 mHeavyWeightProcess = null;
6877 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6878 // Take care of any launching providers waiting for this process.
6879 cleanupAppInLaunchingProvidersLocked(app, true);
6880 // Take care of any services that are waiting for the process.
6881 mServices.processStartTimedOutLocked(app);
6882 app.kill("start timeout", true);
6884 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6886 removeLruProcessLocked(app);
6887 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6888 Slog.w(TAG, "Unattached app died before backup, skipping");
6889 mHandler.post(new Runnable() {
6893 IBackupManager bm = IBackupManager.Stub.asInterface(
6894 ServiceManager.getService(Context.BACKUP_SERVICE));
6895 bm.agentDisconnected(app.info.packageName);
6896 } catch (RemoteException e) {
6897 // Can't happen; the backup manager is local
6902 if (isPendingBroadcastProcessLocked(pid)) {
6903 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6904 skipPendingBroadcastLocked(pid);
6907 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6911 private final boolean attachApplicationLocked(IApplicationThread thread,
6914 // Find the application record that is being attached... either via
6915 // the pid if we are running in multiple processes, or just pull the
6916 // next app record if we are emulating process with anonymous threads.
6918 long startTime = SystemClock.uptimeMillis();
6919 if (pid != MY_PID && pid >= 0) {
6920 synchronized (mPidsSelfLocked) {
6921 app = mPidsSelfLocked.get(pid);
6928 Slog.w(TAG, "No pending application record for pid " + pid
6929 + " (IApplicationThread " + thread + "); dropping process");
6930 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6931 if (pid > 0 && pid != MY_PID) {
6932 killProcessQuiet(pid);
6933 //TODO: killProcessGroup(app.info.uid, pid);
6936 thread.scheduleExit();
6937 } catch (Exception e) {
6938 // Ignore exceptions.
6944 // If this application record is still attached to a previous
6945 // process, clean it up now.
6946 if (app.thread != null) {
6947 handleAppDiedLocked(app, true, true);
6950 // Tell the process all about itself.
6952 if (DEBUG_ALL) Slog.v(
6953 TAG, "Binding process pid " + pid + " to record " + app);
6955 final String processName = app.processName;
6957 AppDeathRecipient adr = new AppDeathRecipient(
6959 thread.asBinder().linkToDeath(adr, 0);
6960 app.deathRecipient = adr;
6961 } catch (RemoteException e) {
6962 app.resetPackageList(mProcessStats);
6963 startProcessLocked(app, "link fail", processName);
6967 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6969 app.makeActive(thread, mProcessStats);
6970 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6971 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6972 app.forcingToImportant = null;
6973 updateProcessForegroundLocked(app, false, false);
6974 app.hasShownUi = false;
6975 app.debugging = false;
6977 app.killedByAm = false;
6981 // We carefully use the same state that PackageManager uses for
6982 // filtering, since we use this flag to decide if we need to install
6983 // providers when user is unlocked later
6984 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6986 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6988 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6989 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6991 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6992 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6994 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6997 checkTime(startTime, "attachApplicationLocked: before bindApplication");
7000 Slog.i(TAG, "Launching preboot mode app: " + app);
7003 if (DEBUG_ALL) Slog.v(
7004 TAG, "New app record " + app
7005 + " thread=" + thread.asBinder() + " pid=" + pid);
7007 int testMode = ApplicationThreadConstants.DEBUG_OFF;
7008 if (mDebugApp != null && mDebugApp.equals(processName)) {
7009 testMode = mWaitForDebugger
7010 ? ApplicationThreadConstants.DEBUG_WAIT
7011 : ApplicationThreadConstants.DEBUG_ON;
7012 app.debugging = true;
7013 if (mDebugTransient) {
7014 mDebugApp = mOrigDebugApp;
7015 mWaitForDebugger = mOrigWaitForDebugger;
7019 ProfilerInfo profilerInfo = null;
7020 String agent = null;
7021 if (mProfileApp != null && mProfileApp.equals(processName)) {
7023 profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7024 new ProfilerInfo(mProfilerInfo) : null;
7025 agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7026 } else if (app.instr != null && app.instr.mProfileFile != null) {
7027 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7031 boolean enableTrackAllocation = false;
7032 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7033 enableTrackAllocation = true;
7034 mTrackAllocationApp = null;
7037 // If the app is being launched for restore or full backup, set it up specially
7038 boolean isRestrictedBackupMode = false;
7039 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7040 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7041 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7042 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7043 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7046 if (app.instr != null) {
7047 notifyPackageUse(app.instr.mClass.getPackageName(),
7048 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7050 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7051 + processName + " with config " + getGlobalConfiguration());
7052 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7053 app.compat = compatibilityInfoForPackageLocked(appInfo);
7055 if (profilerInfo != null && profilerInfo.profileFd != null) {
7056 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7059 // We deprecated Build.SERIAL and it is not accessible to
7060 // apps that target the v2 security sandbox. Since access to
7061 // the serial is now behind a permission we push down the value.
7062 String buildSerial = appInfo.targetSandboxVersion < 2
7063 ? sTheRealBuildSerial : Build.UNKNOWN;
7065 // Check if this is a secondary process that should be incorporated into some
7066 // currently active instrumentation. (Note we do this AFTER all of the profiling
7067 // stuff above because profiling can currently happen only in the primary
7068 // instrumentation process.)
7069 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7070 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7071 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7072 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7073 if (aInstr.mTargetProcesses.length == 0) {
7074 // This is the wildcard mode, where every process brought up for
7075 // the target instrumentation should be included.
7076 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7078 aInstr.mRunningProcesses.add(app);
7081 for (String proc : aInstr.mTargetProcesses) {
7082 if (proc.equals(app.processName)) {
7084 aInstr.mRunningProcesses.add(app);
7093 // If we were asked to attach an agent on startup, do so now, before we're binding
7094 // application code.
7095 if (agent != null) {
7096 thread.attachAgent(agent);
7099 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7100 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7101 if (app.instr != null) {
7102 thread.bindApplication(processName, appInfo, providers,
7104 profilerInfo, app.instr.mArguments,
7106 app.instr.mUiAutomationConnection, testMode,
7107 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7108 isRestrictedBackupMode || !normalMode, app.persistent,
7109 new Configuration(getGlobalConfiguration()), app.compat,
7110 getCommonServicesLocked(app.isolated),
7111 mCoreSettingsObserver.getCoreSettingsLocked(),
7114 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7115 null, null, null, testMode,
7116 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7117 isRestrictedBackupMode || !normalMode, app.persistent,
7118 new Configuration(getGlobalConfiguration()), app.compat,
7119 getCommonServicesLocked(app.isolated),
7120 mCoreSettingsObserver.getCoreSettingsLocked(),
7124 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7125 updateLruProcessLocked(app, false, null);
7126 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7127 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7128 } catch (Exception e) {
7129 // todo: Yikes! What should we do? For now we will try to
7130 // start another process, but that could easily get us in
7131 // an infinite loop of restarting processes...
7132 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7134 app.resetPackageList(mProcessStats);
7135 app.unlinkDeathRecipient();
7136 startProcessLocked(app, "bind fail", processName);
7140 // Remove this record from the list of starting applications.
7141 mPersistentStartingProcesses.remove(app);
7142 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7143 "Attach application locked removing on hold: " + app);
7144 mProcessesOnHold.remove(app);
7146 boolean badApp = false;
7147 boolean didSomething = false;
7149 // See if the top visible activity is waiting to run in this process...
7152 if (mStackSupervisor.attachApplicationLocked(app)) {
7153 didSomething = true;
7155 } catch (Exception e) {
7156 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7161 // Find any services that should be running in this process...
7164 didSomething |= mServices.attachApplicationLocked(app, processName);
7165 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7166 } catch (Exception e) {
7167 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7172 // Check if a next-broadcast receiver is in this process...
7173 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7175 didSomething |= sendPendingBroadcastsLocked(app);
7176 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7177 } catch (Exception e) {
7178 // If the app died trying to launch the receiver we declare it 'bad'
7179 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7184 // Check whether the next backup agent is in this process...
7185 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7186 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7187 "New app is backup target, launching agent for " + app);
7188 notifyPackageUse(mBackupTarget.appInfo.packageName,
7189 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7191 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7192 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7193 mBackupTarget.backupMode);
7194 } catch (Exception e) {
7195 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7201 app.kill("error during init", true);
7202 handleAppDiedLocked(app, false, true);
7206 if (!didSomething) {
7207 updateOomAdjLocked();
7208 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7215 public final void attachApplication(IApplicationThread thread) {
7216 synchronized (this) {
7217 int callingPid = Binder.getCallingPid();
7218 final long origId = Binder.clearCallingIdentity();
7219 attachApplicationLocked(thread, callingPid);
7220 Binder.restoreCallingIdentity(origId);
7225 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7226 final long origId = Binder.clearCallingIdentity();
7227 synchronized (this) {
7228 ActivityStack stack = ActivityRecord.getStackLocked(token);
7229 if (stack != null) {
7231 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7232 false /* processPausingActivities */, config);
7233 if (stopProfiling) {
7234 if ((mProfileProc == r.app) && mProfilerInfo != null) {
7235 clearProfilerLocked();
7240 Binder.restoreCallingIdentity(origId);
7243 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7244 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7245 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7248 void enableScreenAfterBoot() {
7249 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7250 SystemClock.uptimeMillis());
7251 mWindowManager.enableScreenAfterBoot();
7253 synchronized (this) {
7254 updateEventDispatchingLocked();
7259 public void showBootMessage(final CharSequence msg, final boolean always) {
7260 if (Binder.getCallingUid() != myUid()) {
7261 throw new SecurityException();
7263 mWindowManager.showBootMessage(msg, always);
7267 public void keyguardGoingAway(int flags) {
7268 enforceNotIsolatedCaller("keyguardGoingAway");
7269 final long token = Binder.clearCallingIdentity();
7271 synchronized (this) {
7272 mKeyguardController.keyguardGoingAway(flags);
7275 Binder.restoreCallingIdentity(token);
7280 * @return whther the keyguard is currently locked.
7282 boolean isKeyguardLocked() {
7283 return mKeyguardController.isKeyguardLocked();
7286 final void finishBooting() {
7287 synchronized (this) {
7288 if (!mBootAnimationComplete) {
7289 mCallFinishBooting = true;
7292 mCallFinishBooting = false;
7295 ArraySet<String> completedIsas = new ArraySet<String>();
7296 for (String abi : Build.SUPPORTED_ABIS) {
7297 zygoteProcess.establishZygoteConnectionForAbi(abi);
7298 final String instructionSet = VMRuntime.getInstructionSet(abi);
7299 if (!completedIsas.contains(instructionSet)) {
7301 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7302 } catch (InstallerException e) {
7303 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7304 e.getMessage() +")");
7306 completedIsas.add(instructionSet);
7310 IntentFilter pkgFilter = new IntentFilter();
7311 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7312 pkgFilter.addDataScheme("package");
7313 mContext.registerReceiver(new BroadcastReceiver() {
7315 public void onReceive(Context context, Intent intent) {
7316 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7318 for (String pkg : pkgs) {
7319 synchronized (ActivityManagerService.this) {
7320 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7321 0, "query restart")) {
7322 setResultCode(Activity.RESULT_OK);
7331 IntentFilter dumpheapFilter = new IntentFilter();
7332 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7333 mContext.registerReceiver(new BroadcastReceiver() {
7335 public void onReceive(Context context, Intent intent) {
7336 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7337 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7339 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7344 // Let system services know.
7345 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7347 synchronized (this) {
7348 // Ensure that any processes we had put on hold are now started
7350 final int NP = mProcessesOnHold.size();
7352 ArrayList<ProcessRecord> procs =
7353 new ArrayList<ProcessRecord>(mProcessesOnHold);
7354 for (int ip=0; ip<NP; ip++) {
7355 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7357 startProcessLocked(procs.get(ip), "on-hold", null);
7361 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7362 // Start looking for apps that are abusing wake locks.
7363 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7364 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7365 // Tell anyone interested that we are done booting!
7366 SystemProperties.set("sys.boot_completed", "1");
7368 // And trigger dev.bootcomplete if we are not showing encryption progress
7369 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7370 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7371 SystemProperties.set("dev.bootcomplete", "1");
7373 mUserController.sendBootCompletedLocked(
7374 new IIntentReceiver.Stub() {
7376 public void performReceive(Intent intent, int resultCode,
7377 String data, Bundle extras, boolean ordered,
7378 boolean sticky, int sendingUser) {
7379 synchronized (ActivityManagerService.this) {
7380 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7385 scheduleStartProfilesLocked();
7391 public void bootAnimationComplete() {
7392 final boolean callFinishBooting;
7393 synchronized (this) {
7394 callFinishBooting = mCallFinishBooting;
7395 mBootAnimationComplete = true;
7397 if (callFinishBooting) {
7398 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7400 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7404 final void ensureBootCompleted() {
7406 boolean enableScreen;
7407 synchronized (this) {
7410 enableScreen = !mBooted;
7415 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7417 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7421 enableScreenAfterBoot();
7426 public final void activityResumed(IBinder token) {
7427 final long origId = Binder.clearCallingIdentity();
7428 synchronized(this) {
7429 ActivityRecord.activityResumedLocked(token);
7430 mWindowManager.notifyAppResumedFinished(token);
7432 Binder.restoreCallingIdentity(origId);
7436 public final void activityPaused(IBinder token) {
7437 final long origId = Binder.clearCallingIdentity();
7438 synchronized(this) {
7439 ActivityStack stack = ActivityRecord.getStackLocked(token);
7440 if (stack != null) {
7441 stack.activityPausedLocked(token, false);
7444 Binder.restoreCallingIdentity(origId);
7448 public final void activityStopped(IBinder token, Bundle icicle,
7449 PersistableBundle persistentState, CharSequence description) {
7450 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7452 // Refuse possible leaked file descriptors
7453 if (icicle != null && icicle.hasFileDescriptors()) {
7454 throw new IllegalArgumentException("File descriptors passed in Bundle");
7457 final long origId = Binder.clearCallingIdentity();
7459 synchronized (this) {
7460 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7462 r.activityStoppedLocked(icicle, persistentState, description);
7468 Binder.restoreCallingIdentity(origId);
7472 public final void activityDestroyed(IBinder token) {
7473 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7474 synchronized (this) {
7475 ActivityStack stack = ActivityRecord.getStackLocked(token);
7476 if (stack != null) {
7477 stack.activityDestroyedLocked(token, "activityDestroyed");
7483 public final void activityRelaunched(IBinder token) {
7484 final long origId = Binder.clearCallingIdentity();
7485 synchronized (this) {
7486 mStackSupervisor.activityRelaunchedLocked(token);
7488 Binder.restoreCallingIdentity(origId);
7492 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7493 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7494 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7495 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7496 synchronized (this) {
7497 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7498 if (record == null) {
7499 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7500 + "found for: " + token);
7502 record.setSizeConfigurations(horizontalSizeConfiguration,
7503 verticalSizeConfigurations, smallestSizeConfigurations);
7508 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7509 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7513 public final void notifyEnterAnimationComplete(IBinder token) {
7514 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7518 public String getCallingPackage(IBinder token) {
7519 synchronized (this) {
7520 ActivityRecord r = getCallingRecordLocked(token);
7521 return r != null ? r.info.packageName : null;
7526 public ComponentName getCallingActivity(IBinder token) {
7527 synchronized (this) {
7528 ActivityRecord r = getCallingRecordLocked(token);
7529 return r != null ? r.intent.getComponent() : null;
7533 private ActivityRecord getCallingRecordLocked(IBinder token) {
7534 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7542 public ComponentName getActivityClassForToken(IBinder token) {
7543 synchronized(this) {
7544 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7548 return r.intent.getComponent();
7553 public String getPackageForToken(IBinder token) {
7554 synchronized(this) {
7555 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7559 return r.packageName;
7564 public boolean isRootVoiceInteraction(IBinder token) {
7565 synchronized(this) {
7566 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7570 return r.rootVoiceInteraction;
7575 public IIntentSender getIntentSender(int type,
7576 String packageName, IBinder token, String resultWho,
7577 int requestCode, Intent[] intents, String[] resolvedTypes,
7578 int flags, Bundle bOptions, int userId) {
7579 enforceNotIsolatedCaller("getIntentSender");
7580 // Refuse possible leaked file descriptors
7581 if (intents != null) {
7582 if (intents.length < 1) {
7583 throw new IllegalArgumentException("Intents array length must be >= 1");
7585 for (int i=0; i<intents.length; i++) {
7586 Intent intent = intents[i];
7587 if (intent != null) {
7588 if (intent.hasFileDescriptors()) {
7589 throw new IllegalArgumentException("File descriptors passed in Intent");
7591 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7592 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7593 throw new IllegalArgumentException(
7594 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7596 intents[i] = new Intent(intent);
7599 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7600 throw new IllegalArgumentException(
7601 "Intent array length does not match resolvedTypes length");
7604 if (bOptions != null) {
7605 if (bOptions.hasFileDescriptors()) {
7606 throw new IllegalArgumentException("File descriptors passed in options");
7610 synchronized(this) {
7611 int callingUid = Binder.getCallingUid();
7612 int origUserId = userId;
7613 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7614 type == ActivityManager.INTENT_SENDER_BROADCAST,
7615 ALLOW_NON_FULL, "getIntentSender", null);
7616 if (origUserId == UserHandle.USER_CURRENT) {
7617 // We don't want to evaluate this until the pending intent is
7618 // actually executed. However, we do want to always do the
7619 // security checking for it above.
7620 userId = UserHandle.USER_CURRENT;
7623 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7624 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7625 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7626 if (!UserHandle.isSameApp(callingUid, uid)) {
7627 String msg = "Permission Denial: getIntentSender() from pid="
7628 + Binder.getCallingPid()
7629 + ", uid=" + Binder.getCallingUid()
7630 + ", (need uid=" + uid + ")"
7631 + " is not allowed to send as package " + packageName;
7633 throw new SecurityException(msg);
7637 return getIntentSenderLocked(type, packageName, callingUid, userId,
7638 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7640 } catch (RemoteException e) {
7641 throw new SecurityException(e);
7646 IIntentSender getIntentSenderLocked(int type, String packageName,
7647 int callingUid, int userId, IBinder token, String resultWho,
7648 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7650 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7651 ActivityRecord activity = null;
7652 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7653 activity = ActivityRecord.isInStackLocked(token);
7654 if (activity == null) {
7655 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7658 if (activity.finishing) {
7659 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7664 // We're going to be splicing together extras before sending, so we're
7665 // okay poking into any contained extras.
7666 if (intents != null) {
7667 for (int i = 0; i < intents.length; i++) {
7668 intents[i].setDefusable(true);
7671 Bundle.setDefusable(bOptions, true);
7673 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7674 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7675 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7676 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7677 |PendingIntent.FLAG_UPDATE_CURRENT);
7679 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7680 type, packageName, activity, resultWho,
7681 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7682 WeakReference<PendingIntentRecord> ref;
7683 ref = mIntentSenderRecords.get(key);
7684 PendingIntentRecord rec = ref != null ? ref.get() : null;
7686 if (!cancelCurrent) {
7687 if (updateCurrent) {
7688 if (rec.key.requestIntent != null) {
7689 rec.key.requestIntent.replaceExtras(intents != null ?
7690 intents[intents.length - 1] : null);
7692 if (intents != null) {
7693 intents[intents.length-1] = rec.key.requestIntent;
7694 rec.key.allIntents = intents;
7695 rec.key.allResolvedTypes = resolvedTypes;
7697 rec.key.allIntents = null;
7698 rec.key.allResolvedTypes = null;
7703 makeIntentSenderCanceledLocked(rec);
7704 mIntentSenderRecords.remove(key);
7709 rec = new PendingIntentRecord(this, key, callingUid);
7710 mIntentSenderRecords.put(key, rec.ref);
7711 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7712 if (activity.pendingResults == null) {
7713 activity.pendingResults
7714 = new HashSet<WeakReference<PendingIntentRecord>>();
7716 activity.pendingResults.add(rec.ref);
7722 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7723 Intent intent, String resolvedType,
7724 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7725 if (target instanceof PendingIntentRecord) {
7726 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7727 whitelistToken, finishedReceiver, requiredPermission, options);
7729 if (intent == null) {
7730 // Weird case: someone has given us their own custom IIntentSender, and now
7731 // they have someone else trying to send to it but of course this isn't
7732 // really a PendingIntent, so there is no base Intent, and the caller isn't
7733 // supplying an Intent... but we never want to dispatch a null Intent to
7734 // a receiver, so um... let's make something up.
7735 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7736 intent = new Intent(Intent.ACTION_MAIN);
7739 target.send(code, intent, resolvedType, whitelistToken, null,
7740 requiredPermission, options);
7741 } catch (RemoteException e) {
7743 // Platform code can rely on getting a result back when the send is done, but if
7744 // this intent sender is from outside of the system we can't rely on it doing that.
7745 // So instead we don't give it the result receiver, and instead just directly
7746 // report the finish immediately.
7747 if (finishedReceiver != null) {
7749 finishedReceiver.performReceive(intent, 0,
7750 null, null, false, false, UserHandle.getCallingUserId());
7751 } catch (RemoteException e) {
7759 public void cancelIntentSender(IIntentSender sender) {
7760 if (!(sender instanceof PendingIntentRecord)) {
7763 synchronized(this) {
7764 PendingIntentRecord rec = (PendingIntentRecord)sender;
7766 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7767 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7768 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7769 String msg = "Permission Denial: cancelIntentSender() from pid="
7770 + Binder.getCallingPid()
7771 + ", uid=" + Binder.getCallingUid()
7772 + " is not allowed to cancel package "
7773 + rec.key.packageName;
7775 throw new SecurityException(msg);
7777 } catch (RemoteException e) {
7778 throw new SecurityException(e);
7780 cancelIntentSenderLocked(rec, true);
7784 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7785 makeIntentSenderCanceledLocked(rec);
7786 mIntentSenderRecords.remove(rec.key);
7787 if (cleanActivity && rec.key.activity != null) {
7788 rec.key.activity.pendingResults.remove(rec.ref);
7792 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7793 rec.canceled = true;
7794 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7795 if (callbacks != null) {
7796 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7801 public String getPackageForIntentSender(IIntentSender pendingResult) {
7802 if (!(pendingResult instanceof PendingIntentRecord)) {
7806 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7807 return res.key.packageName;
7808 } catch (ClassCastException e) {
7814 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7815 if (!(sender instanceof PendingIntentRecord)) {
7818 synchronized(this) {
7819 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7824 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7825 IResultReceiver receiver) {
7826 if (!(sender instanceof PendingIntentRecord)) {
7829 synchronized(this) {
7830 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7835 public int getUidForIntentSender(IIntentSender sender) {
7836 if (sender instanceof PendingIntentRecord) {
7838 PendingIntentRecord res = (PendingIntentRecord)sender;
7840 } catch (ClassCastException e) {
7847 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7848 if (!(pendingResult instanceof PendingIntentRecord)) {
7852 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7853 if (res.key.allIntents == null) {
7856 for (int i=0; i<res.key.allIntents.length; i++) {
7857 Intent intent = res.key.allIntents[i];
7858 if (intent.getPackage() != null && intent.getComponent() != null) {
7863 } catch (ClassCastException e) {
7869 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7870 if (!(pendingResult instanceof PendingIntentRecord)) {
7874 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7875 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7879 } catch (ClassCastException e) {
7885 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7886 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7887 "getIntentForIntentSender()");
7888 if (!(pendingResult instanceof PendingIntentRecord)) {
7892 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7893 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7894 } catch (ClassCastException e) {
7900 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7901 if (!(pendingResult instanceof PendingIntentRecord)) {
7905 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7906 synchronized (this) {
7907 return getTagForIntentSenderLocked(res, prefix);
7909 } catch (ClassCastException e) {
7914 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7915 final Intent intent = res.key.requestIntent;
7916 if (intent != null) {
7917 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7918 || res.lastTagPrefix.equals(prefix))) {
7921 res.lastTagPrefix = prefix;
7922 final StringBuilder sb = new StringBuilder(128);
7923 if (prefix != null) {
7926 if (intent.getAction() != null) {
7927 sb.append(intent.getAction());
7928 } else if (intent.getComponent() != null) {
7929 intent.getComponent().appendShortString(sb);
7933 return res.lastTag = sb.toString();
7939 public void setProcessLimit(int max) {
7940 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7941 "setProcessLimit()");
7942 synchronized (this) {
7943 mConstants.setOverrideMaxCachedProcesses(max);
7949 public int getProcessLimit() {
7950 synchronized (this) {
7951 return mConstants.getOverrideMaxCachedProcesses();
7955 void importanceTokenDied(ImportanceToken token) {
7956 synchronized (ActivityManagerService.this) {
7957 synchronized (mPidsSelfLocked) {
7959 = mImportantProcesses.get(token.pid);
7963 mImportantProcesses.remove(token.pid);
7964 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7968 pr.forcingToImportant = null;
7969 updateProcessForegroundLocked(pr, false, false);
7971 updateOomAdjLocked();
7976 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7977 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7978 "setProcessImportant()");
7979 synchronized(this) {
7980 boolean changed = false;
7982 synchronized (mPidsSelfLocked) {
7983 ProcessRecord pr = mPidsSelfLocked.get(pid);
7984 if (pr == null && isForeground) {
7985 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7988 ImportanceToken oldToken = mImportantProcesses.get(pid);
7989 if (oldToken != null) {
7990 oldToken.token.unlinkToDeath(oldToken, 0);
7991 mImportantProcesses.remove(pid);
7993 pr.forcingToImportant = null;
7997 if (isForeground && token != null) {
7998 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8000 public void binderDied() {
8001 importanceTokenDied(this);
8005 token.linkToDeath(newToken, 0);
8006 mImportantProcesses.put(pid, newToken);
8007 pr.forcingToImportant = newToken;
8009 } catch (RemoteException e) {
8010 // If the process died while doing this, we will later
8011 // do the cleanup with the process death link.
8017 updateOomAdjLocked();
8023 public boolean isAppForeground(int uid) throws RemoteException {
8024 synchronized (this) {
8025 UidRecord uidRec = mActiveUids.get(uid);
8026 if (uidRec == null || uidRec.idle) {
8029 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8033 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8034 // be guarded by permission checking.
8035 int getUidState(int uid) {
8036 synchronized (this) {
8037 return getUidStateLocked(uid);
8041 int getUidStateLocked(int uid) {
8042 UidRecord uidRec = mActiveUids.get(uid);
8043 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8047 public boolean isInMultiWindowMode(IBinder token) {
8048 final long origId = Binder.clearCallingIdentity();
8050 synchronized(this) {
8051 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8055 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8056 return !r.getTask().mFullscreen;
8059 Binder.restoreCallingIdentity(origId);
8064 public boolean isInPictureInPictureMode(IBinder token) {
8065 final long origId = Binder.clearCallingIdentity();
8067 synchronized(this) {
8068 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8071 Binder.restoreCallingIdentity(origId);
8075 private boolean isInPictureInPictureMode(ActivityRecord r) {
8076 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8077 r.getStack().isInStackLocked(r) == null) {
8081 // If we are animating to fullscreen then we have already dispatched the PIP mode
8082 // changed, so we should reflect that check here as well.
8083 final PinnedActivityStack stack = r.getStack();
8084 final PinnedStackWindowController windowController = stack.getWindowContainerController();
8085 return !windowController.isAnimatingBoundsToFullscreen();
8089 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8090 final long origId = Binder.clearCallingIdentity();
8092 synchronized(this) {
8093 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8094 "enterPictureInPictureMode", token, params);
8096 // If the activity is already in picture in picture mode, then just return early
8097 if (isInPictureInPictureMode(r)) {
8101 // Activity supports picture-in-picture, now check that we can enter PiP at this
8103 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8104 false /* beforeStopping */)) {
8108 final Runnable enterPipRunnable = () -> {
8109 // Only update the saved args from the args that are set
8110 r.pictureInPictureArgs.copyOnlySet(params);
8111 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8112 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8113 // Adjust the source bounds by the insets for the transition down
8114 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8115 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8116 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8117 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8118 stack.setPictureInPictureAspectRatio(aspectRatio);
8119 stack.setPictureInPictureActions(actions);
8121 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8122 r.supportsEnterPipOnTaskSwitch);
8123 logPictureInPictureArgs(params);
8126 if (isKeyguardLocked()) {
8127 // If the keyguard is showing or occluded, then try and dismiss it before
8128 // entering picture-in-picture (this will prompt the user to authenticate if the
8129 // device is currently locked).
8131 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8133 public void onDismissError() throws RemoteException {
8138 public void onDismissSucceeded() throws RemoteException {
8139 mHandler.post(enterPipRunnable);
8143 public void onDismissCancelled() throws RemoteException {
8147 } catch (RemoteException e) {
8151 // Enter picture in picture immediately otherwise
8152 enterPipRunnable.run();
8157 Binder.restoreCallingIdentity(origId);
8162 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8163 final long origId = Binder.clearCallingIdentity();
8165 synchronized(this) {
8166 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8167 "setPictureInPictureParams", token, params);
8169 // Only update the saved args from the args that are set
8170 r.pictureInPictureArgs.copyOnlySet(params);
8171 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8172 // If the activity is already in picture-in-picture, update the pinned stack now
8173 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8174 // be used the next time the activity enters PiP
8175 final PinnedActivityStack stack = r.getStack();
8176 if (!stack.isAnimatingBoundsToFullscreen()) {
8177 stack.setPictureInPictureAspectRatio(
8178 r.pictureInPictureArgs.getAspectRatio());
8179 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8182 logPictureInPictureArgs(params);
8185 Binder.restoreCallingIdentity(origId);
8190 public int getMaxNumPictureInPictureActions(IBinder token) {
8191 // Currently, this is a static constant, but later, we may change this to be dependent on
8192 // the context of the activity
8196 private void logPictureInPictureArgs(PictureInPictureParams params) {
8197 if (params.hasSetActions()) {
8198 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8199 params.getActions().size());
8201 if (params.hasSetAspectRatio()) {
8202 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8203 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8204 MetricsLogger.action(lm);
8209 * Checks the state of the system and the activity associated with the given {@param token} to
8210 * verify that picture-in-picture is supported for that activity.
8212 * @return the activity record for the given {@param token} if all the checks pass.
8214 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8215 IBinder token, PictureInPictureParams params) {
8216 if (!mSupportsPictureInPicture) {
8217 throw new IllegalStateException(caller
8218 + ": Device doesn't support picture-in-picture mode.");
8221 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8223 throw new IllegalStateException(caller
8224 + ": Can't find activity for token=" + token);
8227 if (!r.supportsPictureInPicture()) {
8228 throw new IllegalStateException(caller
8229 + ": Current activity does not support picture-in-picture.");
8232 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8233 throw new IllegalStateException(caller
8234 + ": Activities on the home, assistant, or recents stack not supported");
8237 if (params.hasSetAspectRatio()
8238 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8239 params.getAspectRatio())) {
8240 final float minAspectRatio = mContext.getResources().getFloat(
8241 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8242 final float maxAspectRatio = mContext.getResources().getFloat(
8243 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8244 throw new IllegalArgumentException(String.format(caller
8245 + ": Aspect ratio is too extreme (must be between %f and %f).",
8246 minAspectRatio, maxAspectRatio));
8249 // Truncate the number of actions if necessary
8250 params.truncateActions(getMaxNumPictureInPictureActions(token));
8255 // =========================================================
8257 // =========================================================
8259 static class ProcessInfoService extends IProcessInfoService.Stub {
8260 final ActivityManagerService mActivityManagerService;
8261 ProcessInfoService(ActivityManagerService activityManagerService) {
8262 mActivityManagerService = activityManagerService;
8266 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8267 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8268 /*in*/ pids, /*out*/ states, null);
8272 public void getProcessStatesAndOomScoresFromPids(
8273 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8274 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8275 /*in*/ pids, /*out*/ states, /*out*/ scores);
8280 * For each PID in the given input array, write the current process state
8281 * for that process into the states array, or -1 to indicate that no
8282 * process with the given PID exists. If scores array is provided, write
8283 * the oom score for the process into the scores array, with INVALID_ADJ
8284 * indicating the PID doesn't exist.
8286 public void getProcessStatesAndOomScoresForPIDs(
8287 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8288 if (scores != null) {
8289 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8290 "getProcessStatesAndOomScoresForPIDs()");
8294 throw new NullPointerException("pids");
8295 } else if (states == null) {
8296 throw new NullPointerException("states");
8297 } else if (pids.length != states.length) {
8298 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8299 } else if (scores != null && pids.length != scores.length) {
8300 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8303 synchronized (mPidsSelfLocked) {
8304 for (int i = 0; i < pids.length; i++) {
8305 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8306 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8308 if (scores != null) {
8309 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8315 // =========================================================
8317 // =========================================================
8319 static class PermissionController extends IPermissionController.Stub {
8320 ActivityManagerService mActivityManagerService;
8321 PermissionController(ActivityManagerService activityManagerService) {
8322 mActivityManagerService = activityManagerService;
8326 public boolean checkPermission(String permission, int pid, int uid) {
8327 return mActivityManagerService.checkPermission(permission, pid,
8328 uid) == PackageManager.PERMISSION_GRANTED;
8332 public String[] getPackagesForUid(int uid) {
8333 return mActivityManagerService.mContext.getPackageManager()
8334 .getPackagesForUid(uid);
8338 public boolean isRuntimePermission(String permission) {
8340 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8341 .getPermissionInfo(permission, 0);
8342 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8343 == PermissionInfo.PROTECTION_DANGEROUS;
8344 } catch (NameNotFoundException nnfe) {
8345 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8351 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8353 public int checkComponentPermission(String permission, int pid, int uid,
8354 int owningUid, boolean exported) {
8355 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8356 owningUid, exported);
8360 public Object getAMSLock() {
8361 return ActivityManagerService.this;
8366 * This can be called with or without the global lock held.
8368 int checkComponentPermission(String permission, int pid, int uid,
8369 int owningUid, boolean exported) {
8370 if (pid == MY_PID) {
8371 return PackageManager.PERMISSION_GRANTED;
8373 return ActivityManager.checkComponentPermission(permission, uid,
8374 owningUid, exported);
8378 * As the only public entry point for permissions checking, this method
8379 * can enforce the semantic that requesting a check on a null global
8380 * permission is automatically denied. (Internally a null permission
8381 * string is used when calling {@link #checkComponentPermission} in cases
8382 * when only uid-based security is needed.)
8384 * This can be called with or without the global lock held.
8387 public int checkPermission(String permission, int pid, int uid) {
8388 if (permission == null) {
8389 return PackageManager.PERMISSION_DENIED;
8391 return checkComponentPermission(permission, pid, uid, -1, true);
8395 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8396 if (permission == null) {
8397 return PackageManager.PERMISSION_DENIED;
8400 // We might be performing an operation on behalf of an indirect binder
8401 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8402 // client identity accordingly before proceeding.
8403 Identity tlsIdentity = sCallerIdentity.get();
8404 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8405 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8406 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8407 uid = tlsIdentity.uid;
8408 pid = tlsIdentity.pid;
8411 return checkComponentPermission(permission, pid, uid, -1, true);
8415 * Binder IPC calls go through the public entry point.
8416 * This can be called with or without the global lock held.
8418 int checkCallingPermission(String permission) {
8419 return checkPermission(permission,
8420 Binder.getCallingPid(),
8421 UserHandle.getAppId(Binder.getCallingUid()));
8425 * This can be called with or without the global lock held.
8427 void enforceCallingPermission(String permission, String func) {
8428 if (checkCallingPermission(permission)
8429 == PackageManager.PERMISSION_GRANTED) {
8433 String msg = "Permission Denial: " + func + " from pid="
8434 + Binder.getCallingPid()
8435 + ", uid=" + Binder.getCallingUid()
8436 + " requires " + permission;
8438 throw new SecurityException(msg);
8442 * Determine if UID is holding permissions required to access {@link Uri} in
8443 * the given {@link ProviderInfo}. Final permission checking is always done
8444 * in {@link ContentProvider}.
8446 private final boolean checkHoldingPermissionsLocked(
8447 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8448 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8449 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8450 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8451 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8452 != PERMISSION_GRANTED) {
8456 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8459 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8460 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8461 if (pi.applicationInfo.uid == uid) {
8463 } else if (!pi.exported) {
8467 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8468 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8470 // check if target holds top-level <provider> permissions
8471 if (!readMet && pi.readPermission != null && considerUidPermissions
8472 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8475 if (!writeMet && pi.writePermission != null && considerUidPermissions
8476 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8480 // track if unprotected read/write is allowed; any denied
8481 // <path-permission> below removes this ability
8482 boolean allowDefaultRead = pi.readPermission == null;
8483 boolean allowDefaultWrite = pi.writePermission == null;
8485 // check if target holds any <path-permission> that match uri
8486 final PathPermission[] pps = pi.pathPermissions;
8488 final String path = grantUri.uri.getPath();
8490 while (i > 0 && (!readMet || !writeMet)) {
8492 PathPermission pp = pps[i];
8493 if (pp.match(path)) {
8495 final String pprperm = pp.getReadPermission();
8496 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8497 "Checking read perm for " + pprperm + " for " + pp.getPath()
8498 + ": match=" + pp.match(path)
8499 + " check=" + pm.checkUidPermission(pprperm, uid));
8500 if (pprperm != null) {
8501 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8502 == PERMISSION_GRANTED) {
8505 allowDefaultRead = false;
8510 final String ppwperm = pp.getWritePermission();
8511 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8512 "Checking write perm " + ppwperm + " for " + pp.getPath()
8513 + ": match=" + pp.match(path)
8514 + " check=" + pm.checkUidPermission(ppwperm, uid));
8515 if (ppwperm != null) {
8516 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8517 == PERMISSION_GRANTED) {
8520 allowDefaultWrite = false;
8528 // grant unprotected <provider> read/write, if not blocked by
8529 // <path-permission> above
8530 if (allowDefaultRead) readMet = true;
8531 if (allowDefaultWrite) writeMet = true;
8533 } catch (RemoteException e) {
8537 return readMet && writeMet;
8540 public boolean isAppStartModeDisabled(int uid, String packageName) {
8541 synchronized (this) {
8542 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8543 == ActivityManager.APP_START_MODE_DISABLED;
8547 // Unified app-op and target sdk check
8548 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8549 // Apps that target O+ are always subject to background check
8550 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8551 if (DEBUG_BACKGROUND_CHECK) {
8552 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8554 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8556 // ...and legacy apps get an AppOp check
8557 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8559 if (DEBUG_BACKGROUND_CHECK) {
8560 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8563 case AppOpsManager.MODE_ALLOWED:
8564 return ActivityManager.APP_START_MODE_NORMAL;
8565 case AppOpsManager.MODE_IGNORED:
8566 return ActivityManager.APP_START_MODE_DELAYED;
8568 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8572 // Service launch is available to apps with run-in-background exemptions but
8573 // some other background operations are not. If we're doing a check
8574 // of service-launch policy, allow those callers to proceed unrestricted.
8575 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8577 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8578 if (DEBUG_BACKGROUND_CHECK) {
8579 Slog.i(TAG, "App " + uid + "/" + packageName
8580 + " is persistent; not restricted in background");
8582 return ActivityManager.APP_START_MODE_NORMAL;
8585 // Non-persistent but background whitelisted?
8586 if (uidOnBackgroundWhitelist(uid)) {
8587 if (DEBUG_BACKGROUND_CHECK) {
8588 Slog.i(TAG, "App " + uid + "/" + packageName
8589 + " on background whitelist; not restricted in background");
8591 return ActivityManager.APP_START_MODE_NORMAL;
8594 // Is this app on the battery whitelist?
8595 if (isOnDeviceIdleWhitelistLocked(uid)) {
8596 if (DEBUG_BACKGROUND_CHECK) {
8597 Slog.i(TAG, "App " + uid + "/" + packageName
8598 + " on idle whitelist; not restricted in background");
8600 return ActivityManager.APP_START_MODE_NORMAL;
8603 // None of the service-policy criteria apply, so we apply the common criteria
8604 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8607 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8608 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8609 UidRecord uidRec = mActiveUids.get(uid);
8610 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8611 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8612 + (uidRec != null ? uidRec.idle : false));
8613 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8615 if (uidRec == null) {
8616 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8617 UserHandle.getUserId(uid), packageName);
8619 ephemeral = uidRec.ephemeral;
8623 // We are hard-core about ephemeral apps not running in the background.
8624 return ActivityManager.APP_START_MODE_DISABLED;
8627 // The caller is only interested in whether app starts are completely
8628 // disabled for the given package (that is, it is an instant app). So
8629 // we don't need to go further, which is all just seeing if we should
8630 // apply a "delayed" mode for a regular app.
8631 return ActivityManager.APP_START_MODE_NORMAL;
8633 final int startMode = (alwaysRestrict)
8634 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8635 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8637 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8638 + " pkg=" + packageName + " startMode=" + startMode
8639 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8640 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8641 // This is an old app that has been forced into a "compatible as possible"
8642 // mode of background check. To increase compatibility, we will allow other
8643 // foreground apps to cause its services to start.
8644 if (callingPid >= 0) {
8646 synchronized (mPidsSelfLocked) {
8647 proc = mPidsSelfLocked.get(callingPid);
8650 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8651 // Whoever is instigating this is in the foreground, so we will allow it
8653 return ActivityManager.APP_START_MODE_NORMAL;
8660 return ActivityManager.APP_START_MODE_NORMAL;
8663 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8664 final int appId = UserHandle.getAppId(uid);
8665 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8666 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8667 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8670 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8671 ProviderInfo pi = null;
8672 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8677 pi = AppGlobals.getPackageManager().resolveContentProvider(
8678 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8680 } catch (RemoteException ex) {
8686 void grantEphemeralAccessLocked(int userId, Intent intent,
8687 int targetAppId, int ephemeralAppId) {
8688 getPackageManagerInternalLocked().
8689 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8692 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8693 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8694 if (targetUris != null) {
8695 return targetUris.get(grantUri);
8700 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8701 String targetPkg, int targetUid, GrantUri grantUri) {
8702 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8703 if (targetUris == null) {
8704 targetUris = Maps.newArrayMap();
8705 mGrantedUriPermissions.put(targetUid, targetUris);
8708 UriPermission perm = targetUris.get(grantUri);
8710 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8711 targetUris.put(grantUri, perm);
8717 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8718 final int modeFlags) {
8719 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8720 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8721 : UriPermission.STRENGTH_OWNED;
8723 // Root gets to do everything.
8728 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8729 if (perms == null) return false;
8731 // First look for exact match
8732 final UriPermission exactPerm = perms.get(grantUri);
8733 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8737 // No exact match, look for prefixes
8738 final int N = perms.size();
8739 for (int i = 0; i < N; i++) {
8740 final UriPermission perm = perms.valueAt(i);
8741 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8742 && perm.getStrength(modeFlags) >= minStrength) {
8751 * @param uri This uri must NOT contain an embedded userId.
8752 * @param userId The userId in which the uri is to be resolved.
8755 public int checkUriPermission(Uri uri, int pid, int uid,
8756 final int modeFlags, int userId, IBinder callerToken) {
8757 enforceNotIsolatedCaller("checkUriPermission");
8759 // Another redirected-binder-call permissions check as in
8760 // {@link checkPermissionWithToken}.
8761 Identity tlsIdentity = sCallerIdentity.get();
8762 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8763 uid = tlsIdentity.uid;
8764 pid = tlsIdentity.pid;
8767 // Our own process gets to do everything.
8768 if (pid == MY_PID) {
8769 return PackageManager.PERMISSION_GRANTED;
8771 synchronized (this) {
8772 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8773 ? PackageManager.PERMISSION_GRANTED
8774 : PackageManager.PERMISSION_DENIED;
8779 * Check if the targetPkg can be granted permission to access uri by
8780 * the callingUid using the given modeFlags. Throws a security exception
8781 * if callingUid is not allowed to do this. Returns the uid of the target
8782 * if the URI permission grant should be performed; returns -1 if it is not
8783 * needed (for example targetPkg already has permission to access the URI).
8784 * If you already know the uid of the target, you can supply it in
8785 * lastTargetUid else set that to -1.
8787 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8788 final int modeFlags, int lastTargetUid) {
8789 if (!Intent.isAccessUriMode(modeFlags)) {
8793 if (targetPkg != null) {
8794 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8795 "Checking grant " + targetPkg + " permission to " + grantUri);
8798 final IPackageManager pm = AppGlobals.getPackageManager();
8800 // If this is not a content: uri, we can't do anything with it.
8801 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8802 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8803 "Can't grant URI permission for non-content URI: " + grantUri);
8807 // Bail early if system is trying to hand out permissions directly; it
8808 // must always grant permissions on behalf of someone explicit.
8809 final int callingAppId = UserHandle.getAppId(callingUid);
8810 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8811 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8812 // Exempted authority for cropping user photos in Settings app
8814 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8815 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8820 final String authority = grantUri.uri.getAuthority();
8821 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8822 MATCH_DEBUG_TRIAGED_MISSING);
8824 Slog.w(TAG, "No content provider found for permission check: " +
8825 grantUri.uri.toSafeString());
8829 int targetUid = lastTargetUid;
8830 if (targetUid < 0 && targetPkg != null) {
8832 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8833 UserHandle.getUserId(callingUid));
8834 if (targetUid < 0) {
8835 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8836 "Can't grant URI permission no uid for: " + targetPkg);
8839 } catch (RemoteException ex) {
8844 // If we're extending a persistable grant, then we always need to create
8845 // the grant data structure so that take/release APIs work
8846 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8850 if (targetUid >= 0) {
8851 // First... does the target actually need this permission?
8852 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8853 // No need to grant the target this permission.
8854 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8855 "Target " + targetPkg + " already has full permission to " + grantUri);
8859 // First... there is no target package, so can anyone access it?
8860 boolean allowed = pi.exported;
8861 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8862 if (pi.readPermission != null) {
8866 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8867 if (pi.writePermission != null) {
8876 /* There is a special cross user grant if:
8877 * - The target is on another user.
8878 * - Apps on the current user can access the uri without any uid permissions.
8879 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8880 * grant uri permissions.
8882 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8883 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8884 modeFlags, false /*without considering the uid permissions*/);
8886 // Second... is the provider allowing granting of URI permissions?
8887 if (!specialCrossUserGrant) {
8888 if (!pi.grantUriPermissions) {
8889 throw new SecurityException("Provider " + pi.packageName
8891 + " does not allow granting of Uri permissions (uri "
8894 if (pi.uriPermissionPatterns != null) {
8895 final int N = pi.uriPermissionPatterns.length;
8896 boolean allowed = false;
8897 for (int i=0; i<N; i++) {
8898 if (pi.uriPermissionPatterns[i] != null
8899 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8905 throw new SecurityException("Provider " + pi.packageName
8907 + " does not allow granting of permission to path of Uri "
8913 // Third... does the caller itself have permission to access
8915 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8916 // Require they hold a strong enough Uri permission
8917 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8918 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8919 throw new SecurityException(
8920 "UID " + callingUid + " does not have permission to " + grantUri
8921 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8922 + "or related APIs");
8924 throw new SecurityException(
8925 "UID " + callingUid + " does not have permission to " + grantUri);
8933 * @param uri This uri must NOT contain an embedded userId.
8934 * @param userId The userId in which the uri is to be resolved.
8937 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8938 final int modeFlags, int userId) {
8939 enforceNotIsolatedCaller("checkGrantUriPermission");
8940 synchronized(this) {
8941 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8942 new GrantUri(userId, uri, false), modeFlags, -1);
8946 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8947 final int modeFlags, UriPermissionOwner owner) {
8948 if (!Intent.isAccessUriMode(modeFlags)) {
8952 // So here we are: the caller has the assumed permission
8953 // to the uri, and the target doesn't. Let's now give this to
8956 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8957 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8959 final String authority = grantUri.uri.getAuthority();
8960 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8961 MATCH_DEBUG_TRIAGED_MISSING);
8963 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8967 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8968 grantUri.prefix = true;
8970 final UriPermission perm = findOrCreateUriPermissionLocked(
8971 pi.packageName, targetPkg, targetUid, grantUri);
8972 perm.grantModes(modeFlags, owner);
8975 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8976 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8977 if (targetPkg == null) {
8978 throw new NullPointerException("targetPkg");
8981 final IPackageManager pm = AppGlobals.getPackageManager();
8983 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8984 } catch (RemoteException ex) {
8988 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8990 if (targetUid < 0) {
8994 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8998 static class NeededUriGrants extends ArrayList<GrantUri> {
8999 final String targetPkg;
9000 final int targetUid;
9003 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9004 this.targetPkg = targetPkg;
9005 this.targetUid = targetUid;
9011 * Like checkGrantUriPermissionLocked, but takes an Intent.
9013 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9014 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9015 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9016 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9017 + " clip=" + (intent != null ? intent.getClipData() : null)
9018 + " from " + intent + "; flags=0x"
9019 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9021 if (targetPkg == null) {
9022 throw new NullPointerException("targetPkg");
9025 if (intent == null) {
9028 Uri data = intent.getData();
9029 ClipData clip = intent.getClipData();
9030 if (data == null && clip == null) {
9033 // Default userId for uris in the intent (if they don't specify it themselves)
9034 int contentUserHint = intent.getContentUserHint();
9035 if (contentUserHint == UserHandle.USER_CURRENT) {
9036 contentUserHint = UserHandle.getUserId(callingUid);
9038 final IPackageManager pm = AppGlobals.getPackageManager();
9040 if (needed != null) {
9041 targetUid = needed.targetUid;
9044 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9046 } catch (RemoteException ex) {
9049 if (targetUid < 0) {
9050 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9051 "Can't grant URI permission no uid for: " + targetPkg
9052 + " on user " + targetUserId);
9057 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9058 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9060 if (targetUid > 0) {
9061 if (needed == null) {
9062 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9064 needed.add(grantUri);
9068 for (int i=0; i<clip.getItemCount(); i++) {
9069 Uri uri = clip.getItemAt(i).getUri();
9071 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9072 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9074 if (targetUid > 0) {
9075 if (needed == null) {
9076 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9078 needed.add(grantUri);
9081 Intent clipIntent = clip.getItemAt(i).getIntent();
9082 if (clipIntent != null) {
9083 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9084 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9085 if (newNeeded != null) {
9097 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9099 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9100 UriPermissionOwner owner) {
9101 if (needed != null) {
9102 for (int i=0; i<needed.size(); i++) {
9103 GrantUri grantUri = needed.get(i);
9104 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9105 grantUri, needed.flags, owner);
9110 void grantUriPermissionFromIntentLocked(int callingUid,
9111 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9112 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9113 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9114 if (needed == null) {
9118 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9122 * @param uri This uri must NOT contain an embedded userId.
9123 * @param userId The userId in which the uri is to be resolved.
9126 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9127 final int modeFlags, int userId) {
9128 enforceNotIsolatedCaller("grantUriPermission");
9129 GrantUri grantUri = new GrantUri(userId, uri, false);
9130 synchronized(this) {
9131 final ProcessRecord r = getRecordForAppLocked(caller);
9133 throw new SecurityException("Unable to find app for caller "
9135 + " when granting permission to uri " + grantUri);
9137 if (targetPkg == null) {
9138 throw new IllegalArgumentException("null target");
9140 if (grantUri == null) {
9141 throw new IllegalArgumentException("null uri");
9144 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9145 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9146 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9147 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9149 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9150 UserHandle.getUserId(r.uid));
9154 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9155 if (perm.modeFlags == 0) {
9156 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9158 if (perms != null) {
9159 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9160 "Removing " + perm.targetUid + " permission to " + perm.uri);
9162 perms.remove(perm.uri);
9163 if (perms.isEmpty()) {
9164 mGrantedUriPermissions.remove(perm.targetUid);
9170 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9171 final int modeFlags) {
9172 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9173 "Revoking all granted permissions to " + grantUri);
9175 final IPackageManager pm = AppGlobals.getPackageManager();
9176 final String authority = grantUri.uri.getAuthority();
9177 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9178 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9180 Slog.w(TAG, "No content provider found for permission revoke: "
9181 + grantUri.toSafeString());
9185 // Does the caller have this permission on the URI?
9186 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9187 // If they don't have direct access to the URI, then revoke any
9188 // ownerless URI permissions that have been granted to them.
9189 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9190 if (perms != null) {
9191 boolean persistChanged = false;
9192 for (int i = perms.size()-1; i >= 0; i--) {
9193 final UriPermission perm = perms.valueAt(i);
9194 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9197 if (perm.uri.sourceUserId == grantUri.sourceUserId
9198 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9199 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9200 "Revoking non-owned " + perm.targetUid
9201 + " permission to " + perm.uri);
9202 persistChanged |= perm.revokeModes(
9203 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9204 if (perm.modeFlags == 0) {
9209 if (perms.isEmpty()) {
9210 mGrantedUriPermissions.remove(callingUid);
9212 if (persistChanged) {
9213 schedulePersistUriGrants();
9219 boolean persistChanged = false;
9221 // Go through all of the permissions and remove any that match.
9222 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9223 final int targetUid = mGrantedUriPermissions.keyAt(i);
9224 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9226 for (int j = perms.size()-1; j >= 0; j--) {
9227 final UriPermission perm = perms.valueAt(j);
9228 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9231 if (perm.uri.sourceUserId == grantUri.sourceUserId
9232 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9233 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9234 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9235 persistChanged |= perm.revokeModes(
9236 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9237 targetPackage == null);
9238 if (perm.modeFlags == 0) {
9244 if (perms.isEmpty()) {
9245 mGrantedUriPermissions.removeAt(i);
9249 if (persistChanged) {
9250 schedulePersistUriGrants();
9255 * @param uri This uri must NOT contain an embedded userId.
9256 * @param userId The userId in which the uri is to be resolved.
9259 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9260 final int modeFlags, int userId) {
9261 enforceNotIsolatedCaller("revokeUriPermission");
9262 synchronized(this) {
9263 final ProcessRecord r = getRecordForAppLocked(caller);
9265 throw new SecurityException("Unable to find app for caller "
9267 + " when revoking permission to uri " + uri);
9270 Slog.w(TAG, "revokeUriPermission: null uri");
9274 if (!Intent.isAccessUriMode(modeFlags)) {
9278 final String authority = uri.getAuthority();
9279 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9280 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9282 Slog.w(TAG, "No content provider found for permission revoke: "
9283 + uri.toSafeString());
9287 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9293 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9296 * @param packageName Package name to match, or {@code null} to apply to all
9298 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9300 * @param persistable If persistable grants should be removed.
9302 private void removeUriPermissionsForPackageLocked(
9303 String packageName, int userHandle, boolean persistable) {
9304 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9305 throw new IllegalArgumentException("Must narrow by either package or user");
9308 boolean persistChanged = false;
9310 int N = mGrantedUriPermissions.size();
9311 for (int i = 0; i < N; i++) {
9312 final int targetUid = mGrantedUriPermissions.keyAt(i);
9313 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9315 // Only inspect grants matching user
9316 if (userHandle == UserHandle.USER_ALL
9317 || userHandle == UserHandle.getUserId(targetUid)) {
9318 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9319 final UriPermission perm = it.next();
9321 // Only inspect grants matching package
9322 if (packageName == null || perm.sourcePkg.equals(packageName)
9323 || perm.targetPkg.equals(packageName)) {
9324 // Hacky solution as part of fixing a security bug; ignore
9325 // grants associated with DownloadManager so we don't have
9326 // to immediately launch it to regrant the permissions
9327 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9328 && !persistable) continue;
9330 persistChanged |= perm.revokeModes(persistable
9331 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9333 // Only remove when no modes remain; any persisted grants
9334 // will keep this alive.
9335 if (perm.modeFlags == 0) {
9341 if (perms.isEmpty()) {
9342 mGrantedUriPermissions.remove(targetUid);
9349 if (persistChanged) {
9350 schedulePersistUriGrants();
9355 public IBinder newUriPermissionOwner(String name) {
9356 enforceNotIsolatedCaller("newUriPermissionOwner");
9357 synchronized(this) {
9358 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9359 return owner.getExternalTokenLocked();
9364 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9365 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9366 synchronized(this) {
9367 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9369 throw new IllegalArgumentException("Activity does not exist; token="
9372 return r.getUriPermissionsLocked().getExternalTokenLocked();
9376 * @param uri This uri must NOT contain an embedded userId.
9377 * @param sourceUserId The userId in which the uri is to be resolved.
9378 * @param targetUserId The userId of the app that receives the grant.
9381 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9382 final int modeFlags, int sourceUserId, int targetUserId) {
9383 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9384 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9385 "grantUriPermissionFromOwner", null);
9386 synchronized(this) {
9387 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9388 if (owner == null) {
9389 throw new IllegalArgumentException("Unknown owner: " + token);
9391 if (fromUid != Binder.getCallingUid()) {
9392 if (Binder.getCallingUid() != myUid()) {
9393 // Only system code can grant URI permissions on behalf
9395 throw new SecurityException("nice try");
9398 if (targetPkg == null) {
9399 throw new IllegalArgumentException("null target");
9402 throw new IllegalArgumentException("null uri");
9405 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9406 modeFlags, owner, targetUserId);
9411 * @param uri This uri must NOT contain an embedded userId.
9412 * @param userId The userId in which the uri is to be resolved.
9415 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9416 synchronized(this) {
9417 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9418 if (owner == null) {
9419 throw new IllegalArgumentException("Unknown owner: " + token);
9423 owner.removeUriPermissionsLocked(mode);
9425 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9426 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9431 private void schedulePersistUriGrants() {
9432 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9433 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9434 10 * DateUtils.SECOND_IN_MILLIS);
9438 private void writeGrantedUriPermissions() {
9439 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9441 // Snapshot permissions so we can persist without lock
9442 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9443 synchronized (this) {
9444 final int size = mGrantedUriPermissions.size();
9445 for (int i = 0; i < size; i++) {
9446 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9447 for (UriPermission perm : perms.values()) {
9448 if (perm.persistedModeFlags != 0) {
9449 persist.add(perm.snapshot());
9455 FileOutputStream fos = null;
9457 fos = mGrantFile.startWrite();
9459 XmlSerializer out = new FastXmlSerializer();
9460 out.setOutput(fos, StandardCharsets.UTF_8.name());
9461 out.startDocument(null, true);
9462 out.startTag(null, TAG_URI_GRANTS);
9463 for (UriPermission.Snapshot perm : persist) {
9464 out.startTag(null, TAG_URI_GRANT);
9465 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9466 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9467 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9468 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9469 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9470 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9471 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9472 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9473 out.endTag(null, TAG_URI_GRANT);
9475 out.endTag(null, TAG_URI_GRANTS);
9478 mGrantFile.finishWrite(fos);
9479 } catch (IOException e) {
9481 mGrantFile.failWrite(fos);
9486 private void readGrantedUriPermissionsLocked() {
9487 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9489 final long now = System.currentTimeMillis();
9491 FileInputStream fis = null;
9493 fis = mGrantFile.openRead();
9494 final XmlPullParser in = Xml.newPullParser();
9495 in.setInput(fis, StandardCharsets.UTF_8.name());
9498 while ((type = in.next()) != END_DOCUMENT) {
9499 final String tag = in.getName();
9500 if (type == START_TAG) {
9501 if (TAG_URI_GRANT.equals(tag)) {
9502 final int sourceUserId;
9503 final int targetUserId;
9504 final int userHandle = readIntAttribute(in,
9505 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9506 if (userHandle != UserHandle.USER_NULL) {
9507 // For backwards compatibility.
9508 sourceUserId = userHandle;
9509 targetUserId = userHandle;
9511 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9512 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9514 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9515 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9516 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9517 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9518 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9519 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9521 // Sanity check that provider still belongs to source package
9522 // Both direct boot aware and unaware packages are fine as we
9523 // will do filtering at query time to avoid multiple parsing.
9524 final ProviderInfo pi = getProviderInfoLocked(
9525 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9526 | MATCH_DIRECT_BOOT_UNAWARE);
9527 if (pi != null && sourcePkg.equals(pi.packageName)) {
9530 targetUid = AppGlobals.getPackageManager().getPackageUid(
9531 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9532 } catch (RemoteException e) {
9534 if (targetUid != -1) {
9535 final UriPermission perm = findOrCreateUriPermissionLocked(
9536 sourcePkg, targetPkg, targetUid,
9537 new GrantUri(sourceUserId, uri, prefix));
9538 perm.initPersistedModes(modeFlags, createdTime);
9541 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9542 + " but instead found " + pi);
9547 } catch (FileNotFoundException e) {
9548 // Missing grants is okay
9549 } catch (IOException e) {
9550 Slog.wtf(TAG, "Failed reading Uri grants", e);
9551 } catch (XmlPullParserException e) {
9552 Slog.wtf(TAG, "Failed reading Uri grants", e);
9554 IoUtils.closeQuietly(fis);
9559 * @param uri This uri must NOT contain an embedded userId.
9560 * @param userId The userId in which the uri is to be resolved.
9563 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9564 enforceNotIsolatedCaller("takePersistableUriPermission");
9566 Preconditions.checkFlagsArgument(modeFlags,
9567 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9569 synchronized (this) {
9570 final int callingUid = Binder.getCallingUid();
9571 boolean persistChanged = false;
9572 GrantUri grantUri = new GrantUri(userId, uri, false);
9574 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9575 new GrantUri(userId, uri, false));
9576 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9577 new GrantUri(userId, uri, true));
9579 final boolean exactValid = (exactPerm != null)
9580 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9581 final boolean prefixValid = (prefixPerm != null)
9582 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9584 if (!(exactValid || prefixValid)) {
9585 throw new SecurityException("No persistable permission grants found for UID "
9586 + callingUid + " and Uri " + grantUri.toSafeString());
9590 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9593 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9596 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9598 if (persistChanged) {
9599 schedulePersistUriGrants();
9605 * @param uri This uri must NOT contain an embedded userId.
9606 * @param userId The userId in which the uri is to be resolved.
9609 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9610 enforceNotIsolatedCaller("releasePersistableUriPermission");
9612 Preconditions.checkFlagsArgument(modeFlags,
9613 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9615 synchronized (this) {
9616 final int callingUid = Binder.getCallingUid();
9617 boolean persistChanged = false;
9619 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9620 new GrantUri(userId, uri, false));
9621 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9622 new GrantUri(userId, uri, true));
9623 if (exactPerm == null && prefixPerm == null) {
9624 throw new SecurityException("No permission grants found for UID " + callingUid
9625 + " and Uri " + uri.toSafeString());
9628 if (exactPerm != null) {
9629 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9630 removeUriPermissionIfNeededLocked(exactPerm);
9632 if (prefixPerm != null) {
9633 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9634 removeUriPermissionIfNeededLocked(prefixPerm);
9637 if (persistChanged) {
9638 schedulePersistUriGrants();
9644 * Prune any older {@link UriPermission} for the given UID until outstanding
9645 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9647 * @return if any mutations occured that require persisting.
9649 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9650 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9651 if (perms == null) return false;
9652 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9654 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9655 for (UriPermission perm : perms.values()) {
9656 if (perm.persistedModeFlags != 0) {
9657 persisted.add(perm);
9661 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9662 if (trimCount <= 0) return false;
9664 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9665 for (int i = 0; i < trimCount; i++) {
9666 final UriPermission perm = persisted.get(i);
9668 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9669 "Trimming grant created at " + perm.persistedCreateTime);
9671 perm.releasePersistableModes(~0);
9672 removeUriPermissionIfNeededLocked(perm);
9679 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9680 String packageName, boolean incoming) {
9681 enforceNotIsolatedCaller("getPersistedUriPermissions");
9682 Preconditions.checkNotNull(packageName, "packageName");
9684 final int callingUid = Binder.getCallingUid();
9685 final int callingUserId = UserHandle.getUserId(callingUid);
9686 final IPackageManager pm = AppGlobals.getPackageManager();
9688 final int packageUid = pm.getPackageUid(packageName,
9689 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9690 if (packageUid != callingUid) {
9691 throw new SecurityException(
9692 "Package " + packageName + " does not belong to calling UID " + callingUid);
9694 } catch (RemoteException e) {
9695 throw new SecurityException("Failed to verify package name ownership");
9698 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9699 synchronized (this) {
9701 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9703 if (perms == null) {
9704 Slog.w(TAG, "No permission grants found for " + packageName);
9706 for (UriPermission perm : perms.values()) {
9707 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9708 result.add(perm.buildPersistedPublicApiObject());
9713 final int size = mGrantedUriPermissions.size();
9714 for (int i = 0; i < size; i++) {
9715 final ArrayMap<GrantUri, UriPermission> perms =
9716 mGrantedUriPermissions.valueAt(i);
9717 for (UriPermission perm : perms.values()) {
9718 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9719 result.add(perm.buildPersistedPublicApiObject());
9725 return new ParceledListSlice<android.content.UriPermission>(result);
9729 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9730 String packageName, int userId) {
9731 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9732 "getGrantedUriPermissions");
9734 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9735 synchronized (this) {
9736 final int size = mGrantedUriPermissions.size();
9737 for (int i = 0; i < size; i++) {
9738 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9739 for (UriPermission perm : perms.values()) {
9740 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9741 && perm.persistedModeFlags != 0) {
9742 result.add(perm.buildPersistedPublicApiObject());
9747 return new ParceledListSlice<android.content.UriPermission>(result);
9751 public void clearGrantedUriPermissions(String packageName, int userId) {
9752 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9753 "clearGrantedUriPermissions");
9754 removeUriPermissionsForPackageLocked(packageName, userId, true);
9758 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9759 synchronized (this) {
9761 who != null ? getRecordForAppLocked(who) : null;
9762 if (app == null) return;
9764 Message msg = Message.obtain();
9765 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9767 msg.arg1 = waiting ? 1 : 0;
9768 mUiHandler.sendMessage(msg);
9773 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9774 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9775 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9776 outInfo.availMem = getFreeMemory();
9777 outInfo.totalMem = getTotalMemory();
9778 outInfo.threshold = homeAppMem;
9779 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9780 outInfo.hiddenAppThreshold = cachedAppMem;
9781 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9782 ProcessList.SERVICE_ADJ);
9783 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9784 ProcessList.VISIBLE_APP_ADJ);
9785 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9786 ProcessList.FOREGROUND_APP_ADJ);
9789 // =========================================================
9791 // =========================================================
9794 public List<IBinder> getAppTasks(String callingPackage) {
9795 int callingUid = Binder.getCallingUid();
9796 long ident = Binder.clearCallingIdentity();
9798 synchronized(this) {
9799 ArrayList<IBinder> list = new ArrayList<IBinder>();
9801 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9803 final int N = mRecentTasks.size();
9804 for (int i = 0; i < N; i++) {
9805 TaskRecord tr = mRecentTasks.get(i);
9806 // Skip tasks that do not match the caller. We don't need to verify
9807 // callingPackage, because we are also limiting to callingUid and know
9808 // that will limit to the correct security sandbox.
9809 if (tr.effectiveUid != callingUid) {
9812 Intent intent = tr.getBaseIntent();
9813 if (intent == null ||
9814 !callingPackage.equals(intent.getComponent().getPackageName())) {
9817 ActivityManager.RecentTaskInfo taskInfo =
9818 createRecentTaskInfoFromTaskRecord(tr);
9819 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9820 list.add(taskImpl.asBinder());
9823 Binder.restoreCallingIdentity(ident);
9830 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9831 final int callingUid = Binder.getCallingUid();
9832 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9834 synchronized(this) {
9835 if (DEBUG_ALL) Slog.v(
9836 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9838 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9841 // TODO: Improve with MRU list from all ActivityStacks.
9842 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9849 * Creates a new RecentTaskInfo from a TaskRecord.
9851 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9852 // Update the task description to reflect any changes in the task stack
9853 tr.updateTaskDescription();
9855 // Compose the recent task info
9856 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9857 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9858 rti.persistentId = tr.taskId;
9859 rti.baseIntent = new Intent(tr.getBaseIntent());
9860 rti.origActivity = tr.origActivity;
9861 rti.realActivity = tr.realActivity;
9862 rti.description = tr.lastDescription;
9863 rti.stackId = tr.getStackId();
9864 rti.userId = tr.userId;
9865 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9866 rti.firstActiveTime = tr.firstActiveTime;
9867 rti.lastActiveTime = tr.lastActiveTime;
9868 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9869 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9870 rti.numActivities = 0;
9871 if (tr.mBounds != null) {
9872 rti.bounds = new Rect(tr.mBounds);
9874 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9875 rti.resizeMode = tr.mResizeMode;
9877 ActivityRecord base = null;
9878 ActivityRecord top = null;
9881 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9882 tmp = tr.mActivities.get(i);
9883 if (tmp.finishing) {
9887 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9890 rti.numActivities++;
9893 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9894 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9899 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9900 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9901 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9903 if (checkPermission(android.Manifest.permission.GET_TASKS,
9904 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9905 // Temporary compatibility: some existing apps on the system image may
9906 // still be requesting the old permission and not switched to the new
9907 // one; if so, we'll still allow them full access. This means we need
9908 // to see if they are holding the old permission and are a system app.
9910 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9912 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9913 + " is using old GET_TASKS but privileged; allowing");
9915 } catch (RemoteException e) {
9920 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9921 + " does not hold REAL_GET_TASKS; limiting output");
9927 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9929 final int callingUid = Binder.getCallingUid();
9930 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9931 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9933 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9934 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9935 synchronized (this) {
9936 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9938 final boolean detailed = checkCallingPermission(
9939 android.Manifest.permission.GET_DETAILED_TASKS)
9940 == PackageManager.PERMISSION_GRANTED;
9942 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9943 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9944 return ParceledListSlice.emptyList();
9946 mRecentTasks.loadUserRecentsLocked(userId);
9948 final int recentsCount = mRecentTasks.size();
9949 ArrayList<ActivityManager.RecentTaskInfo> res =
9950 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9952 final Set<Integer> includedUsers;
9953 if (includeProfiles) {
9954 includedUsers = mUserController.getProfileIds(userId);
9956 includedUsers = new HashSet<>();
9958 includedUsers.add(Integer.valueOf(userId));
9960 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9961 TaskRecord tr = mRecentTasks.get(i);
9962 // Only add calling user or related users recent tasks
9963 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9964 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9968 if (tr.realActivitySuspended) {
9969 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9973 // Return the entry if desired by the caller. We always return
9974 // the first entry, because callers always expect this to be the
9975 // foreground app. We may filter others if the caller has
9976 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9977 // we should exclude the entry.
9981 || (tr.intent == null)
9982 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9985 // If the caller doesn't have the GET_TASKS permission, then only
9986 // allow them to see a small subset of tasks -- their own and home.
9987 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9988 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9992 final ActivityStack stack = tr.getStack();
9993 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9994 if (stack != null && stack.isHomeOrRecentsStack()) {
9995 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9996 "Skipping, home or recents stack task: " + tr);
10000 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10001 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10002 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10003 "Skipping, top task in docked stack: " + tr);
10007 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10008 if (stack != null && stack.isPinnedStack()) {
10009 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10010 "Skipping, pinned stack task: " + tr);
10014 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10015 // Don't include auto remove tasks that are finished or finishing.
10016 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10017 "Skipping, auto-remove without activity: " + tr);
10020 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10021 && !tr.isAvailable) {
10022 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10023 "Skipping, unavail real act: " + tr);
10027 if (!tr.mUserSetupComplete) {
10028 // Don't include task launched while user is not done setting-up.
10029 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10030 "Skipping, user setup not complete: " + tr);
10034 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10036 rti.baseIntent.replaceExtras((Bundle)null);
10043 return new ParceledListSlice<>(res);
10048 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10049 synchronized (this) {
10050 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10051 "getTaskThumbnail()");
10052 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10053 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10055 return tr.getTaskThumbnailLocked();
10062 public ActivityManager.TaskDescription getTaskDescription(int id) {
10063 synchronized (this) {
10064 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10065 "getTaskDescription()");
10066 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10067 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10069 return tr.lastTaskDescription;
10076 public int addAppTask(IBinder activityToken, Intent intent,
10077 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10078 final int callingUid = Binder.getCallingUid();
10079 final long callingIdent = Binder.clearCallingIdentity();
10082 synchronized (this) {
10083 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10085 throw new IllegalArgumentException("Activity does not exist; token="
10088 ComponentName comp = intent.getComponent();
10089 if (comp == null) {
10090 throw new IllegalArgumentException("Intent " + intent
10091 + " must specify explicit component");
10093 if (thumbnail.getWidth() != mThumbnailWidth
10094 || thumbnail.getHeight() != mThumbnailHeight) {
10095 throw new IllegalArgumentException("Bad thumbnail size: got "
10096 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10097 + mThumbnailWidth + "x" + mThumbnailHeight);
10099 if (intent.getSelector() != null) {
10100 intent.setSelector(null);
10102 if (intent.getSourceBounds() != null) {
10103 intent.setSourceBounds(null);
10105 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10106 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10107 // The caller has added this as an auto-remove task... that makes no
10108 // sense, so turn off auto-remove.
10109 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10112 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10113 mLastAddedTaskActivity = null;
10115 ActivityInfo ainfo = mLastAddedTaskActivity;
10116 if (ainfo == null) {
10117 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10118 comp, 0, UserHandle.getUserId(callingUid));
10119 if (ainfo.applicationInfo.uid != callingUid) {
10120 throw new SecurityException(
10121 "Can't add task for another application: target uid="
10122 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10126 TaskRecord task = new TaskRecord(this,
10127 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10128 ainfo, intent, description, new TaskThumbnailInfo());
10130 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10131 if (trimIdx >= 0) {
10132 // If this would have caused a trim, then we'll abort because that
10133 // means it would be added at the end of the list but then just removed.
10134 return INVALID_TASK_ID;
10137 final int N = mRecentTasks.size();
10138 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10139 final TaskRecord tr = mRecentTasks.remove(N - 1);
10140 tr.removedFromRecents();
10143 task.inRecents = true;
10144 mRecentTasks.add(task);
10145 r.getStack().addTask(task, false, "addAppTask");
10147 task.setLastThumbnailLocked(thumbnail);
10148 task.freeLastThumbnail();
10149 return task.taskId;
10152 Binder.restoreCallingIdentity(callingIdent);
10157 public Point getAppTaskThumbnailSize() {
10158 synchronized (this) {
10159 return new Point(mThumbnailWidth, mThumbnailHeight);
10164 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10165 synchronized (this) {
10166 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10168 r.setTaskDescription(td);
10169 final TaskRecord task = r.getTask();
10170 task.updateTaskDescription();
10171 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10177 public void setTaskResizeable(int taskId, int resizeableMode) {
10178 synchronized (this) {
10179 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10180 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10181 if (task == null) {
10182 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10185 task.setResizeMode(resizeableMode);
10190 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10191 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10192 long ident = Binder.clearCallingIdentity();
10194 synchronized (this) {
10195 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10196 if (task == null) {
10197 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10200 // Place the task in the right stack if it isn't there already based on
10201 // the requested bounds.
10202 // The stack transition logic is:
10203 // - a null bounds on a freeform task moves that task to fullscreen
10204 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10205 // that task to freeform
10206 // - otherwise the task is not moved
10207 int stackId = task.getStackId();
10208 if (!StackId.isTaskResizeAllowed(stackId)) {
10209 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10211 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10212 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10213 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10214 stackId = FREEFORM_WORKSPACE_STACK_ID;
10217 // Reparent the task to the right stack if necessary
10218 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10219 if (stackId != task.getStackId()) {
10220 // Defer resume until the task is resized below
10221 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10222 DEFER_RESUME, "resizeTask");
10223 preserveWindow = false;
10226 // After reparenting (which only resizes the task to the stack bounds), resize the
10227 // task to the actual bounds provided
10228 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10231 Binder.restoreCallingIdentity(ident);
10236 public Rect getTaskBounds(int taskId) {
10237 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10238 long ident = Binder.clearCallingIdentity();
10239 Rect rect = new Rect();
10241 synchronized (this) {
10242 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10243 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10244 if (task == null) {
10245 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10248 if (task.getStack() != null) {
10249 // Return the bounds from window manager since it will be adjusted for various
10250 // things like the presense of a docked stack for tasks that aren't resizeable.
10251 task.getWindowContainerBounds(rect);
10253 // Task isn't in window manager yet since it isn't associated with a stack.
10254 // Return the persist value from activity manager
10255 if (task.mBounds != null) {
10256 rect.set(task.mBounds);
10257 } else if (task.mLastNonFullscreenBounds != null) {
10258 rect.set(task.mLastNonFullscreenBounds);
10263 Binder.restoreCallingIdentity(ident);
10269 public void cancelTaskWindowTransition(int taskId) {
10270 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10271 final long ident = Binder.clearCallingIdentity();
10273 synchronized (this) {
10274 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10275 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10276 if (task == null) {
10277 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10280 task.cancelWindowTransition();
10283 Binder.restoreCallingIdentity(ident);
10288 public void cancelTaskThumbnailTransition(int taskId) {
10289 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10290 final long ident = Binder.clearCallingIdentity();
10292 synchronized (this) {
10293 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10294 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10295 if (task == null) {
10296 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10299 task.cancelThumbnailTransition();
10302 Binder.restoreCallingIdentity(ident);
10307 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10308 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10309 final long ident = Binder.clearCallingIdentity();
10311 final TaskRecord task;
10312 synchronized (this) {
10313 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10314 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10315 if (task == null) {
10316 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10320 // Don't call this while holding the lock as this operation might hit the disk.
10321 return task.getSnapshot(reducedResolution);
10323 Binder.restoreCallingIdentity(ident);
10328 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10329 if (userId != UserHandle.getCallingUserId()) {
10330 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10331 "getTaskDescriptionIcon");
10333 final File passedIconFile = new File(filePath);
10334 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10335 passedIconFile.getName());
10336 if (!legitIconFile.getPath().equals(filePath)
10337 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10338 throw new IllegalArgumentException("Bad file path: " + filePath
10339 + " passed for userId " + userId);
10341 return mRecentTasks.getTaskDescriptionIcon(filePath);
10345 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10346 throws RemoteException {
10347 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10348 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10349 activityOptions.getCustomInPlaceResId() == 0) {
10350 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10351 "with valid animation");
10353 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10354 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10355 activityOptions.getCustomInPlaceResId());
10356 mWindowManager.executeAppTransition();
10359 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10360 // Remove all tasks with activities in the specified package from the list of recent tasks
10361 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10362 TaskRecord tr = mRecentTasks.get(i);
10363 if (tr.userId != userId) continue;
10365 ComponentName cn = tr.intent.getComponent();
10366 if (cn != null && cn.getPackageName().equals(packageName)) {
10367 // If the package name matches, remove the task.
10368 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10373 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10376 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10377 TaskRecord tr = mRecentTasks.get(i);
10378 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10382 ComponentName cn = tr.intent.getComponent();
10383 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10384 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10385 if (sameComponent) {
10386 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10392 public void removeStack(int stackId) {
10393 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10394 if (StackId.isHomeOrRecentsStack(stackId)) {
10395 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10398 synchronized (this) {
10399 final long ident = Binder.clearCallingIdentity();
10401 mStackSupervisor.removeStackLocked(stackId);
10403 Binder.restoreCallingIdentity(ident);
10409 public void moveStackToDisplay(int stackId, int displayId) {
10410 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10412 synchronized (this) {
10413 final long ident = Binder.clearCallingIdentity();
10415 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10416 + " to displayId=" + displayId);
10417 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10419 Binder.restoreCallingIdentity(ident);
10425 public boolean removeTask(int taskId) {
10426 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10427 synchronized (this) {
10428 final long ident = Binder.clearCallingIdentity();
10430 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10432 Binder.restoreCallingIdentity(ident);
10438 * TODO: Add mController hook
10441 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10442 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10444 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10445 synchronized(this) {
10446 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10450 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10451 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10453 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10454 Binder.getCallingUid(), -1, -1, "Task to front")) {
10455 ActivityOptions.abort(options);
10458 final long origId = Binder.clearCallingIdentity();
10460 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10461 if (task == null) {
10462 Slog.d(TAG, "Could not find task for id: "+ taskId);
10465 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10466 mStackSupervisor.showLockTaskToast();
10467 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10470 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10471 if (prev != null) {
10472 task.setTaskToReturnTo(prev);
10474 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10475 false /* forceNonResizable */);
10477 final ActivityRecord topActivity = task.getTopActivity();
10478 if (topActivity != null) {
10480 // We are reshowing a task, use a starting window to hide the initial draw delay
10481 // so the transition can start earlier.
10482 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10483 true /* taskSwitch */, fromRecents);
10486 Binder.restoreCallingIdentity(origId);
10488 ActivityOptions.abort(options);
10492 * Attempts to move a task backwards in z-order (the order of activities within the task is
10495 * There are several possible results of this call:
10496 * - if the task is locked, then we will show the lock toast
10497 * - if there is a task behind the provided task, then that task is made visible and resumed as
10498 * this task is moved to the back
10499 * - otherwise, if there are no other tasks in the stack:
10500 * - if this task is in the pinned stack, then we remove the stack completely, which will
10501 * have the effect of moving the task to the top or bottom of the fullscreen stack
10502 * (depending on whether it is visible)
10503 * - otherwise, we simply return home and hide this task
10505 * @param token A reference to the activity we wish to move
10506 * @param nonRoot If false then this only works if the activity is the root
10507 * of a task; if true it will work for any activity in a task.
10508 * @return Returns true if the move completed, false if not.
10511 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10512 enforceNotIsolatedCaller("moveActivityTaskToBack");
10513 synchronized(this) {
10514 final long origId = Binder.clearCallingIdentity();
10516 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10517 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10518 if (task != null) {
10519 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10522 Binder.restoreCallingIdentity(origId);
10529 public void moveTaskBackwards(int task) {
10530 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10531 "moveTaskBackwards()");
10533 synchronized(this) {
10534 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10535 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10538 final long origId = Binder.clearCallingIdentity();
10539 moveTaskBackwardsLocked(task);
10540 Binder.restoreCallingIdentity(origId);
10544 private final void moveTaskBackwardsLocked(int task) {
10545 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10549 public int createStackOnDisplay(int displayId) throws RemoteException {
10550 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10551 synchronized (this) {
10552 final int stackId = mStackSupervisor.getNextStackId();
10553 final ActivityStack stack =
10554 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10555 if (stack == null) {
10556 return INVALID_STACK_ID;
10558 return stack.mStackId;
10563 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10564 synchronized (this) {
10565 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10566 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10567 return stack.mDisplayId;
10569 return DEFAULT_DISPLAY;
10574 public int getActivityStackId(IBinder token) throws RemoteException {
10575 synchronized (this) {
10576 ActivityStack stack = ActivityRecord.getStackLocked(token);
10577 if (stack == null) {
10578 return INVALID_STACK_ID;
10580 return stack.mStackId;
10585 public void exitFreeformMode(IBinder token) throws RemoteException {
10586 synchronized (this) {
10587 long ident = Binder.clearCallingIdentity();
10589 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10591 throw new IllegalArgumentException(
10592 "exitFreeformMode: No activity record matching token=" + token);
10595 final ActivityStack stack = r.getStack();
10596 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10597 throw new IllegalStateException(
10598 "exitFreeformMode: You can only go fullscreen from freeform.");
10601 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10602 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10603 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10605 Binder.restoreCallingIdentity(ident);
10611 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10612 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10613 if (StackId.isHomeOrRecentsStack(stackId)) {
10614 throw new IllegalArgumentException(
10615 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10617 synchronized (this) {
10618 long ident = Binder.clearCallingIdentity();
10620 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10621 if (task == null) {
10622 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10626 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10627 + " to stackId=" + stackId + " toTop=" + toTop);
10628 if (stackId == DOCKED_STACK_ID) {
10629 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10630 null /* initialBounds */);
10632 task.reparent(stackId, toTop,
10633 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10635 Binder.restoreCallingIdentity(ident);
10641 public void swapDockedAndFullscreenStack() throws RemoteException {
10642 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10643 synchronized (this) {
10644 long ident = Binder.clearCallingIdentity();
10646 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10647 FULLSCREEN_WORKSPACE_STACK_ID);
10648 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10650 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10651 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10653 if (topTask == null || tasks == null || tasks.size() == 0) {
10655 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10659 // TODO: App transition
10660 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10662 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10663 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10664 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10665 final int size = tasks.size();
10666 for (int i = 0; i < size; i++) {
10667 final int id = tasks.get(i).taskId;
10668 if (id == topTask.taskId) {
10672 // Defer the resume until after all the tasks have been moved
10673 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10674 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10675 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10678 // Because we deferred the resume to avoid conflicts with stack switches while
10679 // resuming, we need to do it after all the tasks are moved.
10680 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10681 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10683 mWindowManager.executeAppTransition();
10685 Binder.restoreCallingIdentity(ident);
10691 * Moves the input task to the docked stack.
10693 * @param taskId Id of task to move.
10694 * @param createMode The mode the docked stack should be created in if it doesn't exist
10696 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10698 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10699 * @param toTop If the task and stack should be moved to the top.
10700 * @param animate Whether we should play an animation for the moving the task
10701 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10702 * docked stack. Pass {@code null} to use default bounds.
10705 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10706 Rect initialBounds) {
10707 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10708 synchronized (this) {
10709 long ident = Binder.clearCallingIdentity();
10711 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10712 if (task == null) {
10713 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10717 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10718 + " to createMode=" + createMode + " toTop=" + toTop);
10719 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10721 // Defer resuming until we move the home stack to the front below
10722 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10723 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10724 "moveTaskToDockedStack");
10726 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10730 Binder.restoreCallingIdentity(ident);
10736 * Moves the top activity in the input stackId to the pinned stack.
10738 * @param stackId Id of stack to move the top activity to pinned stack.
10739 * @param bounds Bounds to use for pinned stack.
10741 * @return True if the top activity of the input stack was successfully moved to the pinned
10745 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10746 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10747 synchronized (this) {
10748 if (!mSupportsPictureInPicture) {
10749 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10750 + "Device doesn't support picture-in-picture mode");
10753 long ident = Binder.clearCallingIdentity();
10755 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10757 Binder.restoreCallingIdentity(ident);
10763 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10764 boolean preserveWindows, boolean animate, int animationDuration) {
10765 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10766 long ident = Binder.clearCallingIdentity();
10768 synchronized (this) {
10770 if (stackId == PINNED_STACK_ID) {
10771 final PinnedActivityStack pinnedStack =
10772 mStackSupervisor.getStack(PINNED_STACK_ID);
10773 if (pinnedStack != null) {
10774 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10775 destBounds, animationDuration, false /* fromFullscreen */);
10778 throw new IllegalArgumentException("Stack: " + stackId
10779 + " doesn't support animated resize.");
10782 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10783 null /* tempTaskInsetBounds */, preserveWindows,
10784 allowResizeInDockedMode, !DEFER_RESUME);
10788 Binder.restoreCallingIdentity(ident);
10793 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10794 Rect tempDockedTaskInsetBounds,
10795 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10796 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10797 "resizeDockedStack()");
10798 long ident = Binder.clearCallingIdentity();
10800 synchronized (this) {
10801 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10802 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10806 Binder.restoreCallingIdentity(ident);
10811 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10812 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10813 "resizePinnedStack()");
10814 final long ident = Binder.clearCallingIdentity();
10816 synchronized (this) {
10817 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10820 Binder.restoreCallingIdentity(ident);
10825 * Try to place task to provided position. The final position might be different depending on
10826 * current user and stacks state. The task will be moved to target stack if it's currently in
10830 public void positionTaskInStack(int taskId, int stackId, int position) {
10831 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10832 if (StackId.isHomeOrRecentsStack(stackId)) {
10833 throw new IllegalArgumentException(
10834 "positionTaskInStack: Attempt to change the position of task "
10835 + taskId + " in/to home/recents stack");
10837 synchronized (this) {
10838 long ident = Binder.clearCallingIdentity();
10840 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10841 + taskId + " in stackId=" + stackId + " at position=" + position);
10842 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10843 if (task == null) {
10844 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10848 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10851 // TODO: Have the callers of this API call a separate reparent method if that is
10852 // what they intended to do vs. having this method also do reparenting.
10853 if (task.getStack() == stack) {
10854 // Change position in current stack.
10855 stack.positionChildAt(task, position);
10857 // Reparent to new stack.
10858 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10859 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10862 Binder.restoreCallingIdentity(ident);
10868 public List<StackInfo> getAllStackInfos() {
10869 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10870 long ident = Binder.clearCallingIdentity();
10872 synchronized (this) {
10873 return mStackSupervisor.getAllStackInfosLocked();
10876 Binder.restoreCallingIdentity(ident);
10881 public StackInfo getStackInfo(int stackId) {
10882 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10883 long ident = Binder.clearCallingIdentity();
10885 synchronized (this) {
10886 return mStackSupervisor.getStackInfoLocked(stackId);
10889 Binder.restoreCallingIdentity(ident);
10894 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10895 synchronized(this) {
10896 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10901 public void updateDeviceOwner(String packageName) {
10902 final int callingUid = Binder.getCallingUid();
10903 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10904 throw new SecurityException("updateDeviceOwner called from non-system process");
10906 synchronized (this) {
10907 mDeviceOwnerName = packageName;
10912 public void updateLockTaskPackages(int userId, String[] packages) {
10913 final int callingUid = Binder.getCallingUid();
10914 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10915 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10916 "updateLockTaskPackages()");
10918 synchronized (this) {
10919 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10920 Arrays.toString(packages));
10921 mLockTaskPackages.put(userId, packages);
10922 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10927 void startLockTaskModeLocked(TaskRecord task) {
10928 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10929 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10933 // When a task is locked, dismiss the pinned stack if it exists
10934 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10936 if (pinnedStack != null) {
10937 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10940 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10941 // is initiated by system after the pinning request was shown and locked mode is initiated
10942 // by an authorized app directly
10943 final int callingUid = Binder.getCallingUid();
10944 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10945 long ident = Binder.clearCallingIdentity();
10947 if (!isSystemInitiated) {
10948 task.mLockTaskUid = callingUid;
10949 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10950 // startLockTask() called by app and task mode is lockTaskModeDefault.
10951 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10952 StatusBarManagerInternal statusBarManager =
10953 LocalServices.getService(StatusBarManagerInternal.class);
10954 if (statusBarManager != null) {
10955 statusBarManager.showScreenPinningRequest(task.taskId);
10960 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10961 if (stack == null || task != stack.topTask()) {
10962 throw new IllegalArgumentException("Invalid task, not in foreground");
10965 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10967 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10968 ActivityManager.LOCK_TASK_MODE_PINNED :
10969 ActivityManager.LOCK_TASK_MODE_LOCKED,
10970 "startLockTask", true);
10972 Binder.restoreCallingIdentity(ident);
10977 public void startLockTaskModeById(int taskId) {
10978 synchronized (this) {
10979 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10980 if (task != null) {
10981 startLockTaskModeLocked(task);
10987 public void startLockTaskModeByToken(IBinder token) {
10988 synchronized (this) {
10989 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10993 final TaskRecord task = r.getTask();
10994 if (task != null) {
10995 startLockTaskModeLocked(task);
11001 public void startSystemLockTaskMode(int taskId) throws RemoteException {
11002 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11003 // This makes inner call to look as if it was initiated by system.
11004 long ident = Binder.clearCallingIdentity();
11006 synchronized (this) {
11007 startLockTaskModeById(taskId);
11010 Binder.restoreCallingIdentity(ident);
11015 public void stopLockTaskMode() {
11016 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11017 if (lockTask == null) {
11018 // Our work here is done.
11022 final int callingUid = Binder.getCallingUid();
11023 final int lockTaskUid = lockTask.mLockTaskUid;
11024 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11025 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11029 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11030 // It is possible lockTaskMode was started by the system process because
11031 // android:lockTaskMode is set to a locking value in the application manifest
11032 // instead of the app calling startLockTaskMode. In this case
11033 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11034 // {@link TaskRecord.effectiveUid} instead. Also caller with
11035 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11036 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11037 && callingUid != lockTaskUid
11038 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11039 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11040 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11043 long ident = Binder.clearCallingIdentity();
11045 Log.d(TAG, "stopLockTaskMode");
11047 synchronized (this) {
11048 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11049 "stopLockTask", true);
11051 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11053 tm.showInCallScreen(false);
11056 Binder.restoreCallingIdentity(ident);
11061 * This API should be called by SystemUI only when user perform certain action to dismiss
11062 * lock task mode. We should only dismiss pinned lock task mode in this case.
11065 public void stopSystemLockTaskMode() throws RemoteException {
11066 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11067 stopLockTaskMode();
11069 mStackSupervisor.showLockTaskToast();
11074 public boolean isInLockTaskMode() {
11075 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11079 public int getLockTaskModeState() {
11080 synchronized (this) {
11081 return mStackSupervisor.getLockTaskModeState();
11086 public void showLockTaskEscapeMessage(IBinder token) {
11087 synchronized (this) {
11088 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11092 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11097 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11098 throws RemoteException {
11099 synchronized (this) {
11100 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11102 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11106 final long origId = Binder.clearCallingIdentity();
11108 r.setDisablePreviewScreenshots(disable);
11110 Binder.restoreCallingIdentity(origId);
11115 // =========================================================
11116 // CONTENT PROVIDERS
11117 // =========================================================
11119 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11120 List<ProviderInfo> providers = null;
11122 providers = AppGlobals.getPackageManager()
11123 .queryContentProviders(app.processName, app.uid,
11124 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11125 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11127 } catch (RemoteException ex) {
11129 if (DEBUG_MU) Slog.v(TAG_MU,
11130 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11131 int userId = app.userId;
11132 if (providers != null) {
11133 int N = providers.size();
11134 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11135 for (int i=0; i<N; i++) {
11136 // TODO: keep logic in sync with installEncryptionUnawareProviders
11138 (ProviderInfo)providers.get(i);
11139 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11140 cpi.name, cpi.flags);
11141 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11142 // This is a singleton provider, but a user besides the
11143 // default user is asking to initialize a process it runs
11144 // in... well, no, it doesn't actually run in this process,
11145 // it runs in the process of the default user. Get rid of it.
11146 providers.remove(i);
11152 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11153 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11155 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11156 mProviderMap.putProviderByClass(comp, cpr);
11158 if (DEBUG_MU) Slog.v(TAG_MU,
11159 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11160 app.pubProviders.put(cpi.name, cpr);
11161 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11162 // Don't add this if it is a platform component that is marked
11163 // to run in multiple processes, because this is actually
11164 // part of the framework so doesn't make sense to track as a
11165 // separate apk in the process.
11166 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11169 notifyPackageUse(cpi.applicationInfo.packageName,
11170 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11177 * Check if the calling UID has a possible chance at accessing the provider
11178 * at the given authority and user.
11180 public String checkContentProviderAccess(String authority, int userId) {
11181 if (userId == UserHandle.USER_ALL) {
11182 mContext.enforceCallingOrSelfPermission(
11183 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11184 userId = UserHandle.getCallingUserId();
11187 ProviderInfo cpi = null;
11189 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11190 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11191 | PackageManager.MATCH_DISABLED_COMPONENTS
11192 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11193 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11195 } catch (RemoteException ignored) {
11198 return "Failed to find provider " + authority + " for user " + userId
11199 + "; expected to find a valid ContentProvider for this authority";
11202 ProcessRecord r = null;
11203 synchronized (mPidsSelfLocked) {
11204 r = mPidsSelfLocked.get(Binder.getCallingPid());
11207 return "Failed to find PID " + Binder.getCallingPid();
11210 synchronized (this) {
11211 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11216 * Check if {@link ProcessRecord} has a possible chance at accessing the
11217 * given {@link ProviderInfo}. Final permission checking is always done
11218 * in {@link ContentProvider}.
11220 private final String checkContentProviderPermissionLocked(
11221 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11222 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11223 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11224 boolean checkedGrants = false;
11226 // Looking for cross-user grants before enforcing the typical cross-users permissions
11227 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11228 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11229 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11232 checkedGrants = true;
11234 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11235 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11236 if (userId != tmpTargetUserId) {
11237 // When we actually went to determine the final targer user ID, this ended
11238 // up different than our initial check for the authority. This is because
11239 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11240 // SELF. So we need to re-check the grants again.
11241 checkedGrants = false;
11244 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11245 cpi.applicationInfo.uid, cpi.exported)
11246 == PackageManager.PERMISSION_GRANTED) {
11249 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11250 cpi.applicationInfo.uid, cpi.exported)
11251 == PackageManager.PERMISSION_GRANTED) {
11255 PathPermission[] pps = cpi.pathPermissions;
11257 int i = pps.length;
11260 PathPermission pp = pps[i];
11261 String pprperm = pp.getReadPermission();
11262 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11263 cpi.applicationInfo.uid, cpi.exported)
11264 == PackageManager.PERMISSION_GRANTED) {
11267 String ppwperm = pp.getWritePermission();
11268 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11269 cpi.applicationInfo.uid, cpi.exported)
11270 == PackageManager.PERMISSION_GRANTED) {
11275 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11279 final String suffix;
11280 if (!cpi.exported) {
11281 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11282 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11283 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11285 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11287 final String msg = "Permission Denial: opening provider " + cpi.name
11288 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11289 + ", uid=" + callingUid + ")" + suffix;
11295 * Returns if the ContentProvider has granted a uri to callingUid
11297 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11298 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11299 if (perms != null) {
11300 for (int i=perms.size()-1; i>=0; i--) {
11301 GrantUri grantUri = perms.keyAt(i);
11302 if (grantUri.sourceUserId == userId || !checkUser) {
11303 if (matchesProvider(grantUri.uri, cpi)) {
11313 * Returns true if the uri authority is one of the authorities specified in the provider.
11315 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11316 String uriAuth = uri.getAuthority();
11317 String cpiAuth = cpi.authority;
11318 if (cpiAuth.indexOf(';') == -1) {
11319 return cpiAuth.equals(uriAuth);
11321 String[] cpiAuths = cpiAuth.split(";");
11322 int length = cpiAuths.length;
11323 for (int i = 0; i < length; i++) {
11324 if (cpiAuths[i].equals(uriAuth)) return true;
11329 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11330 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11332 for (int i=0; i<r.conProviders.size(); i++) {
11333 ContentProviderConnection conn = r.conProviders.get(i);
11334 if (conn.provider == cpr) {
11335 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11336 "Adding provider requested by "
11337 + r.processName + " from process "
11338 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11339 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11341 conn.stableCount++;
11342 conn.numStableIncs++;
11344 conn.unstableCount++;
11345 conn.numUnstableIncs++;
11350 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11352 conn.stableCount = 1;
11353 conn.numStableIncs = 1;
11355 conn.unstableCount = 1;
11356 conn.numUnstableIncs = 1;
11358 cpr.connections.add(conn);
11359 r.conProviders.add(conn);
11360 startAssociationLocked(r.uid, r.processName, r.curProcState,
11361 cpr.uid, cpr.name, cpr.info.processName);
11364 cpr.addExternalProcessHandleLocked(externalProcessToken);
11368 boolean decProviderCountLocked(ContentProviderConnection conn,
11369 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11370 if (conn != null) {
11371 cpr = conn.provider;
11372 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11373 "Removing provider requested by "
11374 + conn.client.processName + " from process "
11375 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11376 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11378 conn.stableCount--;
11380 conn.unstableCount--;
11382 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11383 cpr.connections.remove(conn);
11384 conn.client.conProviders.remove(conn);
11385 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11386 // The client is more important than last activity -- note the time this
11387 // is happening, so we keep the old provider process around a bit as last
11388 // activity to avoid thrashing it.
11389 if (cpr.proc != null) {
11390 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11393 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11398 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11402 private void checkTime(long startTime, String where) {
11403 long now = SystemClock.uptimeMillis();
11404 if ((now-startTime) > 50) {
11405 // If we are taking more than 50ms, log about it.
11406 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11410 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11412 PROC_SPACE_TERM|PROC_PARENS,
11413 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11416 private final long[] mProcessStateStatsLongs = new long[1];
11418 boolean isProcessAliveLocked(ProcessRecord proc) {
11419 if (proc.procStatFile == null) {
11420 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11422 mProcessStateStatsLongs[0] = 0;
11423 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11424 mProcessStateStatsLongs, null)) {
11425 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11428 final long state = mProcessStateStatsLongs[0];
11429 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11431 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11434 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11435 String name, IBinder token, boolean stable, int userId) {
11436 ContentProviderRecord cpr;
11437 ContentProviderConnection conn = null;
11438 ProviderInfo cpi = null;
11440 synchronized(this) {
11441 long startTime = SystemClock.uptimeMillis();
11443 ProcessRecord r = null;
11444 if (caller != null) {
11445 r = getRecordForAppLocked(caller);
11447 throw new SecurityException(
11448 "Unable to find app for caller " + caller
11449 + " (pid=" + Binder.getCallingPid()
11450 + ") when getting content provider " + name);
11454 boolean checkCrossUser = true;
11456 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11458 // First check if this content provider has been published...
11459 cpr = mProviderMap.getProviderByName(name, userId);
11460 // If that didn't work, check if it exists for user 0 and then
11461 // verify that it's a singleton provider before using it.
11462 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11463 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11466 if (isSingleton(cpi.processName, cpi.applicationInfo,
11467 cpi.name, cpi.flags)
11468 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11469 userId = UserHandle.USER_SYSTEM;
11470 checkCrossUser = false;
11478 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11479 if (providerRunning) {
11482 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11483 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11485 throw new SecurityException(msg);
11487 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11489 if (r != null && cpr.canRunHere(r)) {
11490 // This provider has been published or is in the process
11491 // of being published... but it is also allowed to run
11492 // in the caller's process, so don't make a connection
11493 // and just let the caller instantiate its own instance.
11494 ContentProviderHolder holder = cpr.newHolder(null);
11495 // don't give caller the provider object, it needs
11496 // to make its own.
11497 holder.provider = null;
11500 // Don't expose providers between normal apps and instant apps
11502 if (AppGlobals.getPackageManager()
11503 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11506 } catch (RemoteException e) {
11509 final long origId = Binder.clearCallingIdentity();
11511 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11513 // In this case the provider instance already exists, so we can
11514 // return it right away.
11515 conn = incProviderCountLocked(r, cpr, token, stable);
11516 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11517 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11518 // If this is a perceptible app accessing the provider,
11519 // make sure to count it as being accessed and thus
11520 // back up on the LRU list. This is good because
11521 // content providers are often expensive to start.
11522 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11523 updateLruProcessLocked(cpr.proc, false, null);
11524 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11528 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11529 final int verifiedAdj = cpr.proc.verifiedAdj;
11530 boolean success = updateOomAdjLocked(cpr.proc, true);
11531 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11532 // if the process has been successfully adjusted. So to reduce races with
11533 // it, we will check whether the process still exists. Note that this doesn't
11534 // completely get rid of races with LMK killing the process, but should make
11535 // them much smaller.
11536 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11539 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11540 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11541 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11542 // NOTE: there is still a race here where a signal could be
11543 // pending on the process even though we managed to update its
11544 // adj level. Not sure what to do about this, but at least
11545 // the race is now smaller.
11547 // Uh oh... it looks like the provider's process
11548 // has been killed on us. We need to wait for a new
11549 // process to be started, and make sure its death
11550 // doesn't kill our process.
11551 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11552 + " is crashing; detaching " + r);
11553 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11554 checkTime(startTime, "getContentProviderImpl: before appDied");
11555 appDiedLocked(cpr.proc);
11556 checkTime(startTime, "getContentProviderImpl: after appDied");
11558 // This wasn't the last ref our process had on
11559 // the provider... we have now been killed, bail.
11562 providerRunning = false;
11565 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11568 Binder.restoreCallingIdentity(origId);
11571 if (!providerRunning) {
11573 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11574 cpi = AppGlobals.getPackageManager().
11575 resolveContentProvider(name,
11576 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11577 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11578 } catch (RemoteException ex) {
11583 // If the provider is a singleton AND
11584 // (it's a call within the same user || the provider is a
11586 // Then allow connecting to the singleton provider
11587 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11588 cpi.name, cpi.flags)
11589 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11591 userId = UserHandle.USER_SYSTEM;
11593 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11594 checkTime(startTime, "getContentProviderImpl: got app info for user");
11597 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11598 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11600 throw new SecurityException(msg);
11602 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11604 if (!mProcessesReady
11605 && !cpi.processName.equals("system")) {
11606 // If this content provider does not run in the system
11607 // process, and the system is not yet ready to run other
11608 // processes, then fail fast instead of hanging.
11609 throw new IllegalArgumentException(
11610 "Attempt to launch content provider before system ready");
11613 // Make sure that the user who owns this provider is running. If not,
11614 // we don't want to allow it to run.
11615 if (!mUserController.isUserRunningLocked(userId, 0)) {
11616 Slog.w(TAG, "Unable to launch app "
11617 + cpi.applicationInfo.packageName + "/"
11618 + cpi.applicationInfo.uid + " for provider "
11619 + name + ": user " + userId + " is stopped");
11623 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11624 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11625 cpr = mProviderMap.getProviderByClass(comp, userId);
11626 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11627 final boolean firstClass = cpr == null;
11629 final long ident = Binder.clearCallingIdentity();
11631 // If permissions need a review before any of the app components can run,
11632 // we return no provider and launch a review activity if the calling app
11633 // is in the foreground.
11634 if (mPermissionReviewRequired) {
11635 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11641 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11642 ApplicationInfo ai =
11643 AppGlobals.getPackageManager().
11644 getApplicationInfo(
11645 cpi.applicationInfo.packageName,
11646 STOCK_PM_FLAGS, userId);
11647 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11649 Slog.w(TAG, "No package info for content provider "
11653 ai = getAppInfoForUser(ai, userId);
11654 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11655 } catch (RemoteException ex) {
11656 // pm is in same process, this will never happen.
11658 Binder.restoreCallingIdentity(ident);
11662 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11664 if (r != null && cpr.canRunHere(r)) {
11665 // If this is a multiprocess provider, then just return its
11666 // info and allow the caller to instantiate it. Only do
11667 // this if the provider is the same user as the caller's
11668 // process, or can run as root (so can be in any process).
11669 return cpr.newHolder(null);
11672 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11673 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11674 + cpr.info.name + " callers=" + Debug.getCallers(6));
11676 // This is single process, and our app is now connecting to it.
11677 // See if we are already in the process of launching this
11679 final int N = mLaunchingProviders.size();
11681 for (i = 0; i < N; i++) {
11682 if (mLaunchingProviders.get(i) == cpr) {
11687 // If the provider is not already being launched, then get it
11690 final long origId = Binder.clearCallingIdentity();
11693 // Content provider is now in use, its package can't be stopped.
11695 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11696 AppGlobals.getPackageManager().setPackageStoppedState(
11697 cpr.appInfo.packageName, false, userId);
11698 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11699 } catch (RemoteException e) {
11700 } catch (IllegalArgumentException e) {
11701 Slog.w(TAG, "Failed trying to unstop package "
11702 + cpr.appInfo.packageName + ": " + e);
11705 // Use existing process if already started
11706 checkTime(startTime, "getContentProviderImpl: looking for process record");
11707 ProcessRecord proc = getProcessRecordLocked(
11708 cpi.processName, cpr.appInfo.uid, false);
11709 if (proc != null && proc.thread != null && !proc.killed) {
11710 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11711 "Installing in existing process " + proc);
11712 if (!proc.pubProviders.containsKey(cpi.name)) {
11713 checkTime(startTime, "getContentProviderImpl: scheduling install");
11714 proc.pubProviders.put(cpi.name, cpr);
11716 proc.thread.scheduleInstallProvider(cpi);
11717 } catch (RemoteException e) {
11721 checkTime(startTime, "getContentProviderImpl: before start process");
11722 proc = startProcessLocked(cpi.processName,
11723 cpr.appInfo, false, 0, "content provider",
11724 new ComponentName(cpi.applicationInfo.packageName,
11725 cpi.name), false, false, false);
11726 checkTime(startTime, "getContentProviderImpl: after start process");
11727 if (proc == null) {
11728 Slog.w(TAG, "Unable to launch app "
11729 + cpi.applicationInfo.packageName + "/"
11730 + cpi.applicationInfo.uid + " for provider "
11731 + name + ": process is bad");
11735 cpr.launchingApp = proc;
11736 mLaunchingProviders.add(cpr);
11738 Binder.restoreCallingIdentity(origId);
11742 checkTime(startTime, "getContentProviderImpl: updating data structures");
11744 // Make sure the provider is published (the same provider class
11745 // may be published under multiple names).
11747 mProviderMap.putProviderByClass(comp, cpr);
11750 mProviderMap.putProviderByName(name, cpr);
11751 conn = incProviderCountLocked(r, cpr, token, stable);
11752 if (conn != null) {
11753 conn.waiting = true;
11756 checkTime(startTime, "getContentProviderImpl: done!");
11758 grantEphemeralAccessLocked(userId, null /*intent*/,
11759 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11762 // Wait for the provider to be published...
11763 synchronized (cpr) {
11764 while (cpr.provider == null) {
11765 if (cpr.launchingApp == null) {
11766 Slog.w(TAG, "Unable to launch app "
11767 + cpi.applicationInfo.packageName + "/"
11768 + cpi.applicationInfo.uid + " for provider "
11769 + name + ": launching app became null");
11770 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11771 UserHandle.getUserId(cpi.applicationInfo.uid),
11772 cpi.applicationInfo.packageName,
11773 cpi.applicationInfo.uid, name);
11777 if (DEBUG_MU) Slog.v(TAG_MU,
11778 "Waiting to start provider " + cpr
11779 + " launchingApp=" + cpr.launchingApp);
11780 if (conn != null) {
11781 conn.waiting = true;
11784 } catch (InterruptedException ex) {
11786 if (conn != null) {
11787 conn.waiting = false;
11792 return cpr != null ? cpr.newHolder(conn) : null;
11795 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11796 ProcessRecord r, final int userId) {
11797 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11798 cpi.packageName, userId)) {
11800 final boolean callerForeground = r == null || r.setSchedGroup
11801 != ProcessList.SCHED_GROUP_BACKGROUND;
11803 // Show a permission review UI only for starting from a foreground app
11804 if (!callerForeground) {
11805 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11806 + cpi.packageName + " requires a permissions review");
11810 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11811 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11812 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11813 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11815 if (DEBUG_PERMISSIONS_REVIEW) {
11816 Slog.i(TAG, "u" + userId + " Launching permission review "
11817 + "for package " + cpi.packageName);
11820 final UserHandle userHandle = new UserHandle(userId);
11821 mHandler.post(new Runnable() {
11823 public void run() {
11824 mContext.startActivityAsUser(intent, userHandle);
11834 PackageManagerInternal getPackageManagerInternalLocked() {
11835 if (mPackageManagerInt == null) {
11836 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11838 return mPackageManagerInt;
11842 public final ContentProviderHolder getContentProvider(
11843 IApplicationThread caller, String name, int userId, boolean stable) {
11844 enforceNotIsolatedCaller("getContentProvider");
11845 if (caller == null) {
11846 String msg = "null IApplicationThread when getting content provider "
11849 throw new SecurityException(msg);
11851 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11852 // with cross-user grant.
11853 return getContentProviderImpl(caller, name, null, stable, userId);
11856 public ContentProviderHolder getContentProviderExternal(
11857 String name, int userId, IBinder token) {
11858 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11859 "Do not have permission in call getContentProviderExternal()");
11860 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11861 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11862 return getContentProviderExternalUnchecked(name, token, userId);
11865 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11866 IBinder token, int userId) {
11867 return getContentProviderImpl(null, name, token, true, userId);
11871 * Drop a content provider from a ProcessRecord's bookkeeping
11873 public void removeContentProvider(IBinder connection, boolean stable) {
11874 enforceNotIsolatedCaller("removeContentProvider");
11875 long ident = Binder.clearCallingIdentity();
11877 synchronized (this) {
11878 ContentProviderConnection conn;
11880 conn = (ContentProviderConnection)connection;
11881 } catch (ClassCastException e) {
11882 String msg ="removeContentProvider: " + connection
11883 + " not a ContentProviderConnection";
11885 throw new IllegalArgumentException(msg);
11887 if (conn == null) {
11888 throw new NullPointerException("connection is null");
11890 if (decProviderCountLocked(conn, null, null, stable)) {
11891 updateOomAdjLocked();
11895 Binder.restoreCallingIdentity(ident);
11899 public void removeContentProviderExternal(String name, IBinder token) {
11900 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11901 "Do not have permission in call removeContentProviderExternal()");
11902 int userId = UserHandle.getCallingUserId();
11903 long ident = Binder.clearCallingIdentity();
11905 removeContentProviderExternalUnchecked(name, token, userId);
11907 Binder.restoreCallingIdentity(ident);
11911 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11912 synchronized (this) {
11913 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11915 //remove from mProvidersByClass
11916 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11920 //update content provider record entry info
11921 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11922 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11923 if (localCpr.hasExternalProcessHandles()) {
11924 if (localCpr.removeExternalProcessHandleLocked(token)) {
11925 updateOomAdjLocked();
11927 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11928 + " with no external reference for token: "
11932 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11933 + " with no external references.");
11938 public final void publishContentProviders(IApplicationThread caller,
11939 List<ContentProviderHolder> providers) {
11940 if (providers == null) {
11944 enforceNotIsolatedCaller("publishContentProviders");
11945 synchronized (this) {
11946 final ProcessRecord r = getRecordForAppLocked(caller);
11947 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11949 throw new SecurityException(
11950 "Unable to find app for caller " + caller
11951 + " (pid=" + Binder.getCallingPid()
11952 + ") when publishing content providers");
11955 final long origId = Binder.clearCallingIdentity();
11957 final int N = providers.size();
11958 for (int i = 0; i < N; i++) {
11959 ContentProviderHolder src = providers.get(i);
11960 if (src == null || src.info == null || src.provider == null) {
11963 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11964 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11966 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11967 mProviderMap.putProviderByClass(comp, dst);
11968 String names[] = dst.info.authority.split(";");
11969 for (int j = 0; j < names.length; j++) {
11970 mProviderMap.putProviderByName(names[j], dst);
11973 int launchingCount = mLaunchingProviders.size();
11975 boolean wasInLaunchingProviders = false;
11976 for (j = 0; j < launchingCount; j++) {
11977 if (mLaunchingProviders.get(j) == dst) {
11978 mLaunchingProviders.remove(j);
11979 wasInLaunchingProviders = true;
11984 if (wasInLaunchingProviders) {
11985 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11987 synchronized (dst) {
11988 dst.provider = src.provider;
11992 updateOomAdjLocked(r, true);
11993 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11994 src.info.authority);
11998 Binder.restoreCallingIdentity(origId);
12002 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12003 ContentProviderConnection conn;
12005 conn = (ContentProviderConnection)connection;
12006 } catch (ClassCastException e) {
12007 String msg ="refContentProvider: " + connection
12008 + " not a ContentProviderConnection";
12010 throw new IllegalArgumentException(msg);
12012 if (conn == null) {
12013 throw new NullPointerException("connection is null");
12016 synchronized (this) {
12018 conn.numStableIncs += stable;
12020 stable = conn.stableCount + stable;
12022 throw new IllegalStateException("stableCount < 0: " + stable);
12025 if (unstable > 0) {
12026 conn.numUnstableIncs += unstable;
12028 unstable = conn.unstableCount + unstable;
12029 if (unstable < 0) {
12030 throw new IllegalStateException("unstableCount < 0: " + unstable);
12033 if ((stable+unstable) <= 0) {
12034 throw new IllegalStateException("ref counts can't go to zero here: stable="
12035 + stable + " unstable=" + unstable);
12037 conn.stableCount = stable;
12038 conn.unstableCount = unstable;
12043 public void unstableProviderDied(IBinder connection) {
12044 ContentProviderConnection conn;
12046 conn = (ContentProviderConnection)connection;
12047 } catch (ClassCastException e) {
12048 String msg ="refContentProvider: " + connection
12049 + " not a ContentProviderConnection";
12051 throw new IllegalArgumentException(msg);
12053 if (conn == null) {
12054 throw new NullPointerException("connection is null");
12057 // Safely retrieve the content provider associated with the connection.
12058 IContentProvider provider;
12059 synchronized (this) {
12060 provider = conn.provider.provider;
12063 if (provider == null) {
12064 // Um, yeah, we're way ahead of you.
12068 // Make sure the caller is being honest with us.
12069 if (provider.asBinder().pingBinder()) {
12070 // Er, no, still looks good to us.
12071 synchronized (this) {
12072 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12073 + " says " + conn + " died, but we don't agree");
12078 // Well look at that! It's dead!
12079 synchronized (this) {
12080 if (conn.provider.provider != provider) {
12081 // But something changed... good enough.
12085 ProcessRecord proc = conn.provider.proc;
12086 if (proc == null || proc.thread == null) {
12087 // Seems like the process is already cleaned up.
12091 // As far as we're concerned, this is just like receiving a
12092 // death notification... just a bit prematurely.
12093 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12094 + ") early provider death");
12095 final long ident = Binder.clearCallingIdentity();
12097 appDiedLocked(proc);
12099 Binder.restoreCallingIdentity(ident);
12105 public void appNotRespondingViaProvider(IBinder connection) {
12106 enforceCallingPermission(
12107 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12109 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12110 if (conn == null) {
12111 Slog.w(TAG, "ContentProviderConnection is null");
12115 final ProcessRecord host = conn.provider.proc;
12116 if (host == null) {
12117 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12121 mHandler.post(new Runnable() {
12123 public void run() {
12124 mAppErrors.appNotResponding(host, null, null, false,
12125 "ContentProvider not responding");
12130 public final void installSystemProviders() {
12131 List<ProviderInfo> providers;
12132 synchronized (this) {
12133 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12134 providers = generateApplicationProvidersLocked(app);
12135 if (providers != null) {
12136 for (int i=providers.size()-1; i>=0; i--) {
12137 ProviderInfo pi = (ProviderInfo)providers.get(i);
12138 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12139 Slog.w(TAG, "Not installing system proc provider " + pi.name
12140 + ": not system .apk");
12141 providers.remove(i);
12146 if (providers != null) {
12147 mSystemThread.installSystemProviders(providers);
12150 mConstants.start(mContext.getContentResolver());
12151 mCoreSettingsObserver = new CoreSettingsObserver(this);
12152 mFontScaleSettingObserver = new FontScaleSettingObserver();
12154 // Now that the settings provider is published we can consider sending
12155 // in a rescue party.
12156 RescueParty.onSettingsProviderPublished(mContext);
12158 //mUsageStatsService.monitorPackages();
12161 private void startPersistentApps(int matchFlags) {
12162 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12164 synchronized (this) {
12166 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12167 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12168 for (ApplicationInfo app : apps) {
12169 if (!"android".equals(app.packageName)) {
12170 addAppLocked(app, null, false, null /* ABI override */);
12173 } catch (RemoteException ex) {
12179 * When a user is unlocked, we need to install encryption-unaware providers
12180 * belonging to any running apps.
12182 private void installEncryptionUnawareProviders(int userId) {
12183 // We're only interested in providers that are encryption unaware, and
12184 // we don't care about uninstalled apps, since there's no way they're
12185 // running at this point.
12186 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12188 synchronized (this) {
12189 final int NP = mProcessNames.getMap().size();
12190 for (int ip = 0; ip < NP; ip++) {
12191 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12192 final int NA = apps.size();
12193 for (int ia = 0; ia < NA; ia++) {
12194 final ProcessRecord app = apps.valueAt(ia);
12195 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12197 final int NG = app.pkgList.size();
12198 for (int ig = 0; ig < NG; ig++) {
12200 final String pkgName = app.pkgList.keyAt(ig);
12201 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12202 .getPackageInfo(pkgName, matchFlags, userId);
12203 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12204 for (ProviderInfo pi : pkgInfo.providers) {
12205 // TODO: keep in sync with generateApplicationProvidersLocked
12206 final boolean processMatch = Objects.equals(pi.processName,
12207 app.processName) || pi.multiprocess;
12208 final boolean userMatch = isSingleton(pi.processName,
12209 pi.applicationInfo, pi.name, pi.flags)
12210 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12211 if (processMatch && userMatch) {
12212 Log.v(TAG, "Installing " + pi);
12213 app.thread.scheduleInstallProvider(pi);
12215 Log.v(TAG, "Skipping " + pi);
12219 } catch (RemoteException ignored) {
12228 * Allows apps to retrieve the MIME type of a URI.
12229 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12230 * users, then it does not need permission to access the ContentProvider.
12231 * Either, it needs cross-user uri grants.
12233 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12235 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12236 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12238 public String getProviderMimeType(Uri uri, int userId) {
12239 enforceNotIsolatedCaller("getProviderMimeType");
12240 final String name = uri.getAuthority();
12241 int callingUid = Binder.getCallingUid();
12242 int callingPid = Binder.getCallingPid();
12244 boolean clearedIdentity = false;
12245 synchronized (this) {
12246 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12248 if (canClearIdentity(callingPid, callingUid, userId)) {
12249 clearedIdentity = true;
12250 ident = Binder.clearCallingIdentity();
12252 ContentProviderHolder holder = null;
12254 holder = getContentProviderExternalUnchecked(name, null, userId);
12255 if (holder != null) {
12256 return holder.provider.getType(uri);
12258 } catch (RemoteException e) {
12259 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12261 } catch (Exception e) {
12262 Log.w(TAG, "Exception while determining type of " + uri, e);
12265 // We need to clear the identity to call removeContentProviderExternalUnchecked
12266 if (!clearedIdentity) {
12267 ident = Binder.clearCallingIdentity();
12270 if (holder != null) {
12271 removeContentProviderExternalUnchecked(name, null, userId);
12274 Binder.restoreCallingIdentity(ident);
12281 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12282 if (UserHandle.getUserId(callingUid) == userId) {
12285 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12286 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12287 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12288 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12294 // =========================================================
12295 // GLOBAL MANAGEMENT
12296 // =========================================================
12298 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12299 boolean isolated, int isolatedUid) {
12300 String proc = customProcess != null ? customProcess : info.processName;
12301 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12302 final int userId = UserHandle.getUserId(info.uid);
12303 int uid = info.uid;
12305 if (isolatedUid == 0) {
12306 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12308 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12309 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12310 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12312 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12313 mNextIsolatedProcessUid++;
12314 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12315 // No process for this uid, use it.
12319 if (stepsLeft <= 0) {
12324 // Special case for startIsolatedProcess (internal only), where
12325 // the uid of the isolated process is specified by the caller.
12328 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12330 // Register the isolated UID with this application so BatteryStats knows to
12331 // attribute resource usage to the application.
12333 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12334 // about the process state of the isolated UID *before* it is registered with the
12335 // owning application.
12336 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12338 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12339 if (!mBooted && !mBooting
12340 && userId == UserHandle.USER_SYSTEM
12341 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12342 r.persistent = true;
12343 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12345 addProcessNameLocked(r);
12349 private boolean uidOnBackgroundWhitelist(final int uid) {
12350 final int appId = UserHandle.getAppId(uid);
12351 final int[] whitelist = mBackgroundAppIdWhitelist;
12352 final int N = whitelist.length;
12353 for (int i = 0; i < N; i++) {
12354 if (appId == whitelist[i]) {
12362 public void backgroundWhitelistUid(final int uid) {
12363 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12364 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12367 if (DEBUG_BACKGROUND_CHECK) {
12368 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12370 synchronized (this) {
12371 final int N = mBackgroundAppIdWhitelist.length;
12372 int[] newList = new int[N+1];
12373 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12374 newList[N] = UserHandle.getAppId(uid);
12375 mBackgroundAppIdWhitelist = newList;
12379 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12380 String abiOverride) {
12383 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12390 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12391 updateLruProcessLocked(app, false, null);
12392 updateOomAdjLocked();
12395 // This package really, really can not be stopped.
12397 AppGlobals.getPackageManager().setPackageStoppedState(
12398 info.packageName, false, UserHandle.getUserId(app.uid));
12399 } catch (RemoteException e) {
12400 } catch (IllegalArgumentException e) {
12401 Slog.w(TAG, "Failed trying to unstop package "
12402 + info.packageName + ": " + e);
12405 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12406 app.persistent = true;
12407 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12409 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12410 mPersistentStartingProcesses.add(app);
12411 startProcessLocked(app, "added application",
12412 customProcess != null ? customProcess : app.processName, abiOverride,
12413 null /* entryPoint */, null /* entryPointArgs */);
12419 public void unhandledBack() {
12420 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12421 "unhandledBack()");
12423 synchronized(this) {
12424 final long origId = Binder.clearCallingIdentity();
12426 getFocusedStack().unhandledBackLocked();
12428 Binder.restoreCallingIdentity(origId);
12433 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12434 enforceNotIsolatedCaller("openContentUri");
12435 final int userId = UserHandle.getCallingUserId();
12436 final Uri uri = Uri.parse(uriString);
12437 String name = uri.getAuthority();
12438 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12439 ParcelFileDescriptor pfd = null;
12441 // We record the binder invoker's uid in thread-local storage before
12442 // going to the content provider to open the file. Later, in the code
12443 // that handles all permissions checks, we look for this uid and use
12444 // that rather than the Activity Manager's own uid. The effect is that
12445 // we do the check against the caller's permissions even though it looks
12446 // to the content provider like the Activity Manager itself is making
12448 Binder token = new Binder();
12449 sCallerIdentity.set(new Identity(
12450 token, Binder.getCallingPid(), Binder.getCallingUid()));
12452 pfd = cph.provider.openFile(null, uri, "r", null, token);
12453 } catch (FileNotFoundException e) {
12454 // do nothing; pfd will be returned null
12456 // Ensure that whatever happens, we clean up the identity state
12457 sCallerIdentity.remove();
12458 // Ensure we're done with the provider.
12459 removeContentProviderExternalUnchecked(name, null, userId);
12462 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12467 // Actually is sleeping or shutting down or whatever else in the future
12468 // is an inactive state.
12469 boolean isSleepingOrShuttingDownLocked() {
12470 return isSleepingLocked() || mShuttingDown;
12473 boolean isShuttingDownLocked() {
12474 return mShuttingDown;
12477 boolean isSleepingLocked() {
12481 void onWakefulnessChanged(int wakefulness) {
12482 synchronized(this) {
12483 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12484 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12485 mWakefulness = wakefulness;
12487 if (wasAwake != isAwake) {
12488 // Also update state in a special way for running foreground services UI.
12489 mServices.updateScreenStateLocked(isAwake);
12490 sendNotifyVrManagerOfSleepState(!isAwake);
12495 void finishRunningVoiceLocked() {
12496 if (mRunningVoice != null) {
12497 mRunningVoice = null;
12498 mVoiceWakeLock.release();
12499 updateSleepIfNeededLocked();
12503 void startTimeTrackingFocusedActivityLocked() {
12504 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12505 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12506 mCurAppTimeTracker.start(resumedActivity.packageName);
12510 void updateSleepIfNeededLocked() {
12511 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12512 final boolean wasSleeping = mSleeping;
12514 if (!shouldSleep) {
12515 // If wasSleeping is true, we need to wake up activity manager state from when
12516 // we started sleeping. In either case, we need to apply the sleep tokens, which
12517 // will wake up stacks or put them to sleep as appropriate.
12520 startTimeTrackingFocusedActivityLocked();
12521 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12522 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12524 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12526 updateOomAdjLocked();
12528 } else if (!mSleeping && shouldSleep) {
12530 if (mCurAppTimeTracker != null) {
12531 mCurAppTimeTracker.stop();
12533 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12534 mStackSupervisor.goingToSleepLocked();
12535 updateOomAdjLocked();
12539 /** Pokes the task persister. */
12540 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12541 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12545 * Notifies all listeners when the pinned stack animation starts.
12548 public void notifyPinnedStackAnimationStarted() {
12549 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12553 * Notifies all listeners when the pinned stack animation ends.
12556 public void notifyPinnedStackAnimationEnded() {
12557 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12561 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12562 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12566 public boolean shutdown(int timeout) {
12567 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12568 != PackageManager.PERMISSION_GRANTED) {
12569 throw new SecurityException("Requires permission "
12570 + android.Manifest.permission.SHUTDOWN);
12573 boolean timedout = false;
12575 synchronized(this) {
12576 mShuttingDown = true;
12577 mStackSupervisor.prepareForShutdownLocked();
12578 updateEventDispatchingLocked();
12579 timedout = mStackSupervisor.shutdownLocked(timeout);
12582 mAppOpsService.shutdown();
12583 if (mUsageStatsService != null) {
12584 mUsageStatsService.prepareShutdown();
12586 mBatteryStatsService.shutdown();
12587 synchronized (this) {
12588 mProcessStats.shutdownLocked();
12589 notifyTaskPersisterLocked(null, true);
12595 public final void activitySlept(IBinder token) {
12596 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12598 final long origId = Binder.clearCallingIdentity();
12600 synchronized (this) {
12601 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12603 mStackSupervisor.activitySleptLocked(r);
12607 Binder.restoreCallingIdentity(origId);
12610 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12611 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12612 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12613 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12614 boolean wasRunningVoice = mRunningVoice != null;
12615 mRunningVoice = session;
12616 if (!wasRunningVoice) {
12617 mVoiceWakeLock.acquire();
12618 updateSleepIfNeededLocked();
12623 private void updateEventDispatchingLocked() {
12624 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12628 public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12629 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12630 != PackageManager.PERMISSION_GRANTED) {
12631 throw new SecurityException("Requires permission "
12632 + android.Manifest.permission.DEVICE_POWER);
12635 synchronized(this) {
12636 long ident = Binder.clearCallingIdentity();
12638 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12640 Binder.restoreCallingIdentity(ident);
12643 sendNotifyVrManagerOfKeyguardState(showing);
12647 public void notifyLockedProfile(@UserIdInt int userId) {
12649 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12650 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12652 } catch (RemoteException ex) {
12653 throw new SecurityException("Fail to check is caller a privileged app", ex);
12656 synchronized (this) {
12657 final long ident = Binder.clearCallingIdentity();
12659 if (mUserController.shouldConfirmCredentials(userId)) {
12660 if (mKeyguardController.isKeyguardLocked()) {
12661 // Showing launcher to avoid user entering credential twice.
12662 final int currentUserId = mUserController.getCurrentUserIdLocked();
12663 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12665 mStackSupervisor.lockAllProfileTasks(userId);
12668 Binder.restoreCallingIdentity(ident);
12674 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12675 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12676 synchronized (this) {
12677 final long ident = Binder.clearCallingIdentity();
12679 mActivityStarter.startConfirmCredentialIntent(intent, options);
12681 Binder.restoreCallingIdentity(ident);
12687 public void stopAppSwitches() {
12688 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12689 != PackageManager.PERMISSION_GRANTED) {
12690 throw new SecurityException("viewquires permission "
12691 + android.Manifest.permission.STOP_APP_SWITCHES);
12694 synchronized(this) {
12695 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12696 + APP_SWITCH_DELAY_TIME;
12697 mDidAppSwitch = false;
12698 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12699 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12700 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12704 public void resumeAppSwitches() {
12705 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12706 != PackageManager.PERMISSION_GRANTED) {
12707 throw new SecurityException("Requires permission "
12708 + android.Manifest.permission.STOP_APP_SWITCHES);
12711 synchronized(this) {
12712 // Note that we don't execute any pending app switches... we will
12713 // let those wait until either the timeout, or the next start
12714 // activity request.
12715 mAppSwitchesAllowedTime = 0;
12719 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12720 int callingPid, int callingUid, String name) {
12721 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12725 int perm = checkComponentPermission(
12726 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12727 sourceUid, -1, true);
12728 if (perm == PackageManager.PERMISSION_GRANTED) {
12732 // If the actual IPC caller is different from the logical source, then
12733 // also see if they are allowed to control app switches.
12734 if (callingUid != -1 && callingUid != sourceUid) {
12735 perm = checkComponentPermission(
12736 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12737 callingUid, -1, true);
12738 if (perm == PackageManager.PERMISSION_GRANTED) {
12743 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12747 public void setDebugApp(String packageName, boolean waitForDebugger,
12748 boolean persistent) {
12749 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12752 long ident = Binder.clearCallingIdentity();
12754 // Note that this is not really thread safe if there are multiple
12755 // callers into it at the same time, but that's not a situation we
12758 final ContentResolver resolver = mContext.getContentResolver();
12759 Settings.Global.putString(
12760 resolver, Settings.Global.DEBUG_APP,
12762 Settings.Global.putInt(
12763 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12764 waitForDebugger ? 1 : 0);
12767 synchronized (this) {
12769 mOrigDebugApp = mDebugApp;
12770 mOrigWaitForDebugger = mWaitForDebugger;
12772 mDebugApp = packageName;
12773 mWaitForDebugger = waitForDebugger;
12774 mDebugTransient = !persistent;
12775 if (packageName != null) {
12776 forceStopPackageLocked(packageName, -1, false, false, true, true,
12777 false, UserHandle.USER_ALL, "set debug app");
12781 Binder.restoreCallingIdentity(ident);
12785 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12786 synchronized (this) {
12787 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12788 if (!isDebuggable) {
12789 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12790 throw new SecurityException("Process not debuggable: " + app.packageName);
12794 mTrackAllocationApp = processName;
12798 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12799 synchronized (this) {
12800 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12801 if (!isDebuggable) {
12802 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12803 throw new SecurityException("Process not debuggable: " + app.packageName);
12806 mProfileApp = processName;
12808 if (mProfilerInfo != null) {
12809 if (mProfilerInfo.profileFd != null) {
12811 mProfilerInfo.profileFd.close();
12812 } catch (IOException e) {
12816 mProfilerInfo = new ProfilerInfo(profilerInfo);
12821 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12822 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12823 if (!isDebuggable) {
12824 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12825 throw new SecurityException("Process not debuggable: " + app.packageName);
12828 mNativeDebuggingApp = processName;
12832 public void setAlwaysFinish(boolean enabled) {
12833 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12834 "setAlwaysFinish()");
12836 long ident = Binder.clearCallingIdentity();
12838 Settings.Global.putInt(
12839 mContext.getContentResolver(),
12840 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12842 synchronized (this) {
12843 mAlwaysFinishActivities = enabled;
12846 Binder.restoreCallingIdentity(ident);
12851 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12852 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12853 "setActivityController()");
12854 synchronized (this) {
12855 mController = controller;
12856 mControllerIsAMonkey = imAMonkey;
12857 Watchdog.getInstance().setActivityController(controller);
12862 public void setUserIsMonkey(boolean userIsMonkey) {
12863 synchronized (this) {
12864 synchronized (mPidsSelfLocked) {
12865 final int callingPid = Binder.getCallingPid();
12866 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12867 if (proc == null) {
12868 throw new SecurityException("Unknown process: " + callingPid);
12870 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12871 throw new SecurityException("Only an instrumentation process "
12872 + "with a UiAutomation can call setUserIsMonkey");
12875 mUserIsMonkey = userIsMonkey;
12880 public boolean isUserAMonkey() {
12881 synchronized (this) {
12882 // If there is a controller also implies the user is a monkey.
12883 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12888 * @deprecated This method is only used by a few internal components and it will soon be
12889 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12890 * No new code should be calling it.
12894 public void requestBugReport(int bugreportType) {
12895 String extraOptions = null;
12896 switch (bugreportType) {
12897 case ActivityManager.BUGREPORT_OPTION_FULL:
12898 // Default options.
12900 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12901 extraOptions = "bugreportplus";
12903 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12904 extraOptions = "bugreportremote";
12906 case ActivityManager.BUGREPORT_OPTION_WEAR:
12907 extraOptions = "bugreportwear";
12909 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12910 extraOptions = "bugreporttelephony";
12913 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12916 // Always log caller, even if it does not have permission to dump.
12917 String type = extraOptions == null ? "bugreport" : extraOptions;
12918 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12920 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12921 if (extraOptions != null) {
12922 SystemProperties.set("dumpstate.options", extraOptions);
12924 SystemProperties.set("ctl.start", "bugreport");
12928 * @deprecated This method is only used by a few internal components and it will soon be
12929 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12930 * No new code should be calling it.
12934 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12936 if (!TextUtils.isEmpty(shareTitle)) {
12937 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12938 String errorStr = "shareTitle should be less than " +
12939 MAX_BUGREPORT_TITLE_SIZE + " characters";
12940 throw new IllegalArgumentException(errorStr);
12942 if (!TextUtils.isEmpty(shareDescription)) {
12945 length = shareDescription.getBytes("UTF-8").length;
12946 } catch (UnsupportedEncodingException e) {
12947 String errorStr = "shareDescription: UnsupportedEncodingException";
12948 throw new IllegalArgumentException(errorStr);
12950 if (length > SystemProperties.PROP_VALUE_MAX) {
12951 String errorStr = "shareTitle should be less than " +
12952 SystemProperties.PROP_VALUE_MAX + " bytes";
12953 throw new IllegalArgumentException(errorStr);
12955 SystemProperties.set("dumpstate.options.description", shareDescription);
12958 SystemProperties.set("dumpstate.options.title", shareTitle);
12962 Slog.d(TAG, "Bugreport notification title " + shareTitle
12963 + " description " + shareDescription);
12964 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12967 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12968 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12971 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12972 if (r != null && (r.instr != null || r.usingWrapper)) {
12973 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12975 return KEY_DISPATCHING_TIMEOUT;
12979 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12980 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12981 != PackageManager.PERMISSION_GRANTED) {
12982 throw new SecurityException("Requires permission "
12983 + android.Manifest.permission.FILTER_EVENTS);
12985 ProcessRecord proc;
12987 synchronized (this) {
12988 synchronized (mPidsSelfLocked) {
12989 proc = mPidsSelfLocked.get(pid);
12991 timeout = getInputDispatchingTimeoutLocked(proc);
12994 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13002 * Handle input dispatching timeouts.
13003 * Returns whether input dispatching should be aborted or not.
13005 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13006 final ActivityRecord activity, final ActivityRecord parent,
13007 final boolean aboveSystem, String reason) {
13008 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13009 != PackageManager.PERMISSION_GRANTED) {
13010 throw new SecurityException("Requires permission "
13011 + android.Manifest.permission.FILTER_EVENTS);
13014 final String annotation;
13015 if (reason == null) {
13016 annotation = "Input dispatching timed out";
13018 annotation = "Input dispatching timed out (" + reason + ")";
13021 if (proc != null) {
13022 synchronized (this) {
13023 if (proc.debugging) {
13027 if (proc.instr != null) {
13028 Bundle info = new Bundle();
13029 info.putString("shortMsg", "keyDispatchingTimedOut");
13030 info.putString("longMsg", annotation);
13031 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13035 mHandler.post(new Runnable() {
13037 public void run() {
13038 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13047 public Bundle getAssistContextExtras(int requestType) {
13048 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13049 null, null, true /* focused */, true /* newSessionId */,
13050 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13054 synchronized (pae) {
13055 while (!pae.haveResult) {
13058 } catch (InterruptedException e) {
13062 synchronized (this) {
13063 buildAssistBundleLocked(pae, pae.result);
13064 mPendingAssistExtras.remove(pae);
13065 mUiHandler.removeCallbacks(pae);
13071 public boolean isAssistDataAllowedOnCurrentActivity() {
13073 synchronized (this) {
13074 final ActivityStack focusedStack = getFocusedStack();
13075 if (focusedStack == null || focusedStack.isAssistantStack()) {
13079 final ActivityRecord activity = focusedStack.topActivity();
13080 if (activity == null) {
13083 userId = activity.userId;
13085 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13086 Context.DEVICE_POLICY_SERVICE);
13087 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13091 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13092 long ident = Binder.clearCallingIdentity();
13094 synchronized (this) {
13095 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13096 ActivityRecord top = getFocusedStack().topActivity();
13097 if (top != caller) {
13098 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13099 + " is not current top " + top);
13102 if (!top.nowVisible) {
13103 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13104 + " is not visible");
13108 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13111 Binder.restoreCallingIdentity(ident);
13116 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13117 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13118 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13119 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13120 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13124 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13125 IBinder activityToken, int flags) {
13126 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13127 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13128 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13131 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13132 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13133 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13135 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13136 "enqueueAssistContext()");
13138 synchronized (this) {
13139 ActivityRecord activity = getFocusedStack().topActivity();
13140 if (activity == null) {
13141 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13144 if (activity.app == null || activity.app.thread == null) {
13145 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13149 if (activityToken != null) {
13150 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13151 if (activity != caller) {
13152 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13153 + " is not current top " + activity);
13158 activity = ActivityRecord.forTokenLocked(activityToken);
13159 if (activity == null) {
13160 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13161 + " couldn't be found");
13164 if (activity.app == null || activity.app.thread == null) {
13165 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13170 PendingAssistExtras pae;
13171 Bundle extras = new Bundle();
13172 if (args != null) {
13173 extras.putAll(args);
13175 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13176 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13178 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13180 pae.isHome = activity.isHomeActivity();
13182 // Increment the sessionId if necessary
13183 if (newSessionId) {
13187 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13188 mViSessionId, flags);
13189 mPendingAssistExtras.add(pae);
13190 mUiHandler.postDelayed(pae, timeout);
13191 } catch (RemoteException e) {
13192 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13199 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13200 IResultReceiver receiver;
13201 synchronized (this) {
13202 mPendingAssistExtras.remove(pae);
13203 receiver = pae.receiver;
13205 if (receiver != null) {
13206 // Caller wants result sent back to them.
13207 Bundle sendBundle = new Bundle();
13208 // At least return the receiver extras
13209 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13210 pae.receiverExtras);
13212 pae.receiver.send(0, sendBundle);
13213 } catch (RemoteException e) {
13218 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13219 if (result != null) {
13220 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13222 if (pae.hint != null) {
13223 pae.extras.putBoolean(pae.hint, true);
13227 /** Called from an app when assist data is ready. */
13229 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13230 AssistContent content, Uri referrer) {
13231 PendingAssistExtras pae = (PendingAssistExtras)token;
13232 synchronized (pae) {
13233 pae.result = extras;
13234 pae.structure = structure;
13235 pae.content = content;
13236 if (referrer != null) {
13237 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13239 if (structure != null) {
13240 structure.setHomeActivity(pae.isHome);
13242 pae.haveResult = true;
13244 if (pae.intent == null && pae.receiver == null) {
13245 // Caller is just waiting for the result.
13249 // We are now ready to launch the assist activity.
13250 IResultReceiver sendReceiver = null;
13251 Bundle sendBundle = null;
13252 synchronized (this) {
13253 buildAssistBundleLocked(pae, extras);
13254 boolean exists = mPendingAssistExtras.remove(pae);
13255 mUiHandler.removeCallbacks(pae);
13260 if ((sendReceiver=pae.receiver) != null) {
13261 // Caller wants result sent back to them.
13262 sendBundle = new Bundle();
13263 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13264 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13265 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13266 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13267 pae.receiverExtras);
13270 if (sendReceiver != null) {
13272 sendReceiver.send(0, sendBundle);
13273 } catch (RemoteException e) {
13278 final long ident = Binder.clearCallingIdentity();
13280 if (TextUtils.equals(pae.intent.getAction(),
13281 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13282 pae.intent.putExtras(pae.extras);
13283 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13285 pae.intent.replaceExtras(pae.extras);
13286 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13287 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13288 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13289 closeSystemDialogs("assist");
13292 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13293 } catch (ActivityNotFoundException e) {
13294 Slog.w(TAG, "No activity to handle assist action.", e);
13298 Binder.restoreCallingIdentity(ident);
13302 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13304 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13305 true /* focused */, true /* newSessionId */, userHandle, args,
13306 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13309 public void registerProcessObserver(IProcessObserver observer) {
13310 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13311 "registerProcessObserver()");
13312 synchronized (this) {
13313 mProcessObservers.register(observer);
13318 public void unregisterProcessObserver(IProcessObserver observer) {
13319 synchronized (this) {
13320 mProcessObservers.unregister(observer);
13325 public int getUidProcessState(int uid, String callingPackage) {
13326 if (!hasUsageStatsPermission(callingPackage)) {
13327 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13328 "getUidProcessState");
13331 synchronized (this) {
13332 UidRecord uidRec = mActiveUids.get(uid);
13333 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13338 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13339 String callingPackage) {
13340 if (!hasUsageStatsPermission(callingPackage)) {
13341 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13342 "registerUidObserver");
13344 synchronized (this) {
13345 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13346 callingPackage, which, cutpoint));
13351 public void unregisterUidObserver(IUidObserver observer) {
13352 synchronized (this) {
13353 mUidObservers.unregister(observer);
13358 public boolean convertFromTranslucent(IBinder token) {
13359 final long origId = Binder.clearCallingIdentity();
13361 synchronized (this) {
13362 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13366 final boolean translucentChanged = r.changeWindowTranslucency(true);
13367 if (translucentChanged) {
13368 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13370 mWindowManager.setAppFullscreen(token, true);
13371 return translucentChanged;
13374 Binder.restoreCallingIdentity(origId);
13379 public boolean convertToTranslucent(IBinder token, Bundle options) {
13380 final long origId = Binder.clearCallingIdentity();
13382 synchronized (this) {
13383 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13387 final TaskRecord task = r.getTask();
13388 int index = task.mActivities.lastIndexOf(r);
13390 ActivityRecord under = task.mActivities.get(index - 1);
13391 under.returningOptions = ActivityOptions.fromBundle(options);
13393 final boolean translucentChanged = r.changeWindowTranslucency(false);
13394 if (translucentChanged) {
13395 r.getStack().convertActivityToTranslucent(r);
13397 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13398 mWindowManager.setAppFullscreen(token, false);
13399 return translucentChanged;
13402 Binder.restoreCallingIdentity(origId);
13407 public Bundle getActivityOptions(IBinder token) {
13408 final long origId = Binder.clearCallingIdentity();
13410 synchronized (this) {
13411 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13413 final ActivityOptions activityOptions = r.takeOptionsLocked();
13414 return activityOptions == null ? null : activityOptions.toBundle();
13419 Binder.restoreCallingIdentity(origId);
13424 public void setImmersive(IBinder token, boolean immersive) {
13425 synchronized(this) {
13426 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13428 throw new IllegalArgumentException();
13430 r.immersive = immersive;
13432 // update associated state if we're frontmost
13433 if (r == mStackSupervisor.getResumedActivityLocked()) {
13434 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13435 applyUpdateLockStateLocked(r);
13441 public boolean isImmersive(IBinder token) {
13442 synchronized (this) {
13443 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13445 throw new IllegalArgumentException();
13447 return r.immersive;
13452 public void setVrThread(int tid) {
13453 enforceSystemHasVrFeature();
13454 synchronized (this) {
13455 synchronized (mPidsSelfLocked) {
13456 final int pid = Binder.getCallingPid();
13457 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13458 mVrController.setVrThreadLocked(tid, pid, proc);
13464 public void setPersistentVrThread(int tid) {
13465 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13466 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13467 + Binder.getCallingPid()
13468 + ", uid=" + Binder.getCallingUid()
13469 + " requires " + permission.RESTRICTED_VR_ACCESS;
13471 throw new SecurityException(msg);
13473 enforceSystemHasVrFeature();
13474 synchronized (this) {
13475 synchronized (mPidsSelfLocked) {
13476 final int pid = Binder.getCallingPid();
13477 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13478 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13484 * Schedule the given thread a normal scheduling priority.
13486 * @param tid the tid of the thread to adjust the scheduling of.
13487 * @param suppressLogs {@code true} if any error logging should be disabled.
13489 * @return {@code true} if this succeeded.
13491 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13493 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13495 } catch (IllegalArgumentException e) {
13496 if (!suppressLogs) {
13497 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13499 } catch (SecurityException e) {
13500 if (!suppressLogs) {
13501 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13508 * Schedule the given thread an FIFO scheduling priority.
13510 * @param tid the tid of the thread to adjust the scheduling of.
13511 * @param suppressLogs {@code true} if any error logging should be disabled.
13513 * @return {@code true} if this succeeded.
13515 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13517 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13519 } catch (IllegalArgumentException e) {
13520 if (!suppressLogs) {
13521 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13523 } catch (SecurityException e) {
13524 if (!suppressLogs) {
13525 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13532 * Check that we have the features required for VR-related API calls, and throw an exception if
13535 private void enforceSystemHasVrFeature() {
13536 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13537 throw new UnsupportedOperationException("VR mode not supported on this device!");
13542 public void setRenderThread(int tid) {
13543 synchronized (this) {
13544 ProcessRecord proc;
13545 int pid = Binder.getCallingPid();
13546 if (pid == Process.myPid()) {
13547 demoteSystemServerRenderThread(tid);
13550 synchronized (mPidsSelfLocked) {
13551 proc = mPidsSelfLocked.get(pid);
13552 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13553 // ensure the tid belongs to the process
13554 if (!isThreadInProcess(pid, tid)) {
13555 throw new IllegalArgumentException(
13556 "Render thread does not belong to process");
13558 proc.renderThreadTid = tid;
13559 if (DEBUG_OOM_ADJ) {
13560 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13562 // promote to FIFO now
13563 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13564 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13565 if (mUseFifoUiScheduling) {
13566 setThreadScheduler(proc.renderThreadTid,
13567 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13569 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13573 if (DEBUG_OOM_ADJ) {
13574 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13575 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13576 mUseFifoUiScheduling);
13584 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13585 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13587 * @param tid the tid of the RenderThread
13589 private void demoteSystemServerRenderThread(int tid) {
13590 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13594 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13595 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13596 throw new UnsupportedOperationException("VR mode not supported on this device!");
13599 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13602 synchronized (this) {
13603 r = ActivityRecord.isInStackLocked(token);
13607 throw new IllegalArgumentException();
13611 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13612 VrManagerInternal.NO_ERROR) {
13616 synchronized(this) {
13617 r.requestedVrComponent = (enabled) ? packageName : null;
13619 // Update associated state if this activity is currently focused
13620 if (r == mStackSupervisor.getResumedActivityLocked()) {
13621 applyUpdateVrModeLocked(r);
13628 public boolean isVrModePackageEnabled(ComponentName packageName) {
13629 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13630 throw new UnsupportedOperationException("VR mode not supported on this device!");
13633 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13635 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13636 VrManagerInternal.NO_ERROR;
13639 public boolean isTopActivityImmersive() {
13640 enforceNotIsolatedCaller("startActivity");
13641 synchronized (this) {
13642 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13643 return (r != null) ? r.immersive : false;
13648 * @return whether the system should disable UI modes incompatible with VR mode.
13650 boolean shouldDisableNonVrUiLocked() {
13651 return mVrController.shouldDisableNonVrUiLocked();
13655 public boolean isTopOfTask(IBinder token) {
13656 synchronized (this) {
13657 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13659 throw new IllegalArgumentException();
13661 return r.getTask().getTopActivity() == r;
13666 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13667 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13668 String msg = "Permission Denial: setHasTopUi() from pid="
13669 + Binder.getCallingPid()
13670 + ", uid=" + Binder.getCallingUid()
13671 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13673 throw new SecurityException(msg);
13675 final int pid = Binder.getCallingPid();
13676 final long origId = Binder.clearCallingIdentity();
13678 synchronized (this) {
13679 boolean changed = false;
13681 synchronized (mPidsSelfLocked) {
13682 pr = mPidsSelfLocked.get(pid);
13684 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13687 if (pr.hasTopUi != hasTopUi) {
13688 if (DEBUG_OOM_ADJ) {
13689 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13691 pr.hasTopUi = hasTopUi;
13696 updateOomAdjLocked(pr, true);
13700 Binder.restoreCallingIdentity(origId);
13704 public final void enterSafeMode() {
13705 synchronized(this) {
13706 // It only makes sense to do this before the system is ready
13707 // and started launching other packages.
13708 if (!mSystemReady) {
13710 AppGlobals.getPackageManager().enterSafeMode();
13711 } catch (RemoteException e) {
13719 public final void showSafeModeOverlay() {
13720 View v = LayoutInflater.from(mContext).inflate(
13721 com.android.internal.R.layout.safe_mode, null);
13722 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13723 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13724 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13725 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13726 lp.gravity = Gravity.BOTTOM | Gravity.START;
13727 lp.format = v.getBackground().getOpacity();
13728 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13729 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13730 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13731 ((WindowManager)mContext.getSystemService(
13732 Context.WINDOW_SERVICE)).addView(v, lp);
13735 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13736 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13739 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13740 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13741 synchronized (stats) {
13742 if (mBatteryStatsService.isOnBattery()) {
13743 mBatteryStatsService.enforceCallingPermission();
13744 int MY_UID = Binder.getCallingUid();
13746 if (sender == null) {
13749 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13751 BatteryStatsImpl.Uid.Pkg pkg =
13752 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13753 sourcePkg != null ? sourcePkg : rec.key.packageName);
13754 pkg.noteWakeupAlarmLocked(tag);
13759 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13760 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13763 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13764 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13765 synchronized (stats) {
13766 mBatteryStatsService.enforceCallingPermission();
13767 int MY_UID = Binder.getCallingUid();
13769 if (sender == null) {
13772 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13774 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13778 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13779 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13782 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13783 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13784 synchronized (stats) {
13785 mBatteryStatsService.enforceCallingPermission();
13786 int MY_UID = Binder.getCallingUid();
13788 if (sender == null) {
13791 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13793 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13797 public boolean killPids(int[] pids, String pReason, boolean secure) {
13798 if (Binder.getCallingUid() != SYSTEM_UID) {
13799 throw new SecurityException("killPids only available to the system");
13801 String reason = (pReason == null) ? "Unknown" : pReason;
13802 // XXX Note: don't acquire main activity lock here, because the window
13803 // manager calls in with its locks held.
13805 boolean killed = false;
13806 synchronized (mPidsSelfLocked) {
13808 for (int i=0; i<pids.length; i++) {
13809 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13810 if (proc != null) {
13811 int type = proc.setAdj;
13812 if (type > worstType) {
13818 // If the worst oom_adj is somewhere in the cached proc LRU range,
13819 // then constrain it so we will kill all cached procs.
13820 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13821 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13822 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13825 // If this is not a secure call, don't let it kill processes that
13827 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13828 worstType = ProcessList.SERVICE_ADJ;
13831 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13832 for (int i=0; i<pids.length; i++) {
13833 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13834 if (proc == null) {
13837 int adj = proc.setAdj;
13838 if (adj >= worstType && !proc.killedByAm) {
13839 proc.kill(reason, true);
13848 public void killUid(int appId, int userId, String reason) {
13849 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13850 synchronized (this) {
13851 final long identity = Binder.clearCallingIdentity();
13853 killPackageProcessesLocked(null, appId, userId,
13854 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13855 reason != null ? reason : "kill uid");
13857 Binder.restoreCallingIdentity(identity);
13863 public boolean killProcessesBelowForeground(String reason) {
13864 if (Binder.getCallingUid() != SYSTEM_UID) {
13865 throw new SecurityException("killProcessesBelowForeground() only available to system");
13868 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13871 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13872 if (Binder.getCallingUid() != SYSTEM_UID) {
13873 throw new SecurityException("killProcessesBelowAdj() only available to system");
13876 boolean killed = false;
13877 synchronized (mPidsSelfLocked) {
13878 final int size = mPidsSelfLocked.size();
13879 for (int i = 0; i < size; i++) {
13880 final int pid = mPidsSelfLocked.keyAt(i);
13881 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13882 if (proc == null) continue;
13884 final int adj = proc.setAdj;
13885 if (adj > belowAdj && !proc.killedByAm) {
13886 proc.kill(reason, true);
13895 public void hang(final IBinder who, boolean allowRestart) {
13896 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13897 != PackageManager.PERMISSION_GRANTED) {
13898 throw new SecurityException("Requires permission "
13899 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13902 final IBinder.DeathRecipient death = new DeathRecipient() {
13904 public void binderDied() {
13905 synchronized (this) {
13912 who.linkToDeath(death, 0);
13913 } catch (RemoteException e) {
13914 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13918 synchronized (this) {
13919 Watchdog.getInstance().setAllowRestart(allowRestart);
13920 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13921 synchronized (death) {
13922 while (who.isBinderAlive()) {
13925 } catch (InterruptedException e) {
13929 Watchdog.getInstance().setAllowRestart(true);
13934 public void restart() {
13935 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13936 != PackageManager.PERMISSION_GRANTED) {
13937 throw new SecurityException("Requires permission "
13938 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13941 Log.i(TAG, "Sending shutdown broadcast...");
13943 BroadcastReceiver br = new BroadcastReceiver() {
13944 @Override public void onReceive(Context context, Intent intent) {
13945 // Now the broadcast is done, finish up the low-level shutdown.
13946 Log.i(TAG, "Shutting down activity manager...");
13948 Log.i(TAG, "Shutdown complete, restarting!");
13949 killProcess(myPid());
13954 // First send the high-level shut down broadcast.
13955 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13956 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13957 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13958 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13959 mContext.sendOrderedBroadcastAsUser(intent,
13960 UserHandle.ALL, null, br, mHandler, 0, null, null);
13962 br.onReceive(mContext, intent);
13965 private long getLowRamTimeSinceIdle(long now) {
13966 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13970 public void performIdleMaintenance() {
13971 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13972 != PackageManager.PERMISSION_GRANTED) {
13973 throw new SecurityException("Requires permission "
13974 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13977 synchronized (this) {
13978 final long now = SystemClock.uptimeMillis();
13979 final long timeSinceLastIdle = now - mLastIdleTime;
13980 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13981 mLastIdleTime = now;
13982 mLowRamTimeSinceLastIdle = 0;
13983 if (mLowRamStartTime != 0) {
13984 mLowRamStartTime = now;
13987 StringBuilder sb = new StringBuilder(128);
13988 sb.append("Idle maintenance over ");
13989 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13990 sb.append(" low RAM for ");
13991 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13992 Slog.i(TAG, sb.toString());
13994 // If at least 1/3 of our time since the last idle period has been spent
13995 // with RAM low, then we want to kill processes.
13996 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13998 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13999 ProcessRecord proc = mLruProcesses.get(i);
14000 if (proc.notCachedSinceIdle) {
14001 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14002 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14003 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14004 if (doKilling && proc.initialIdlePss != 0
14005 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14006 sb = new StringBuilder(128);
14008 sb.append(proc.processName);
14009 sb.append(" in idle maint: pss=");
14010 sb.append(proc.lastPss);
14011 sb.append(", swapPss=");
14012 sb.append(proc.lastSwapPss);
14013 sb.append(", initialPss=");
14014 sb.append(proc.initialIdlePss);
14015 sb.append(", period=");
14016 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14017 sb.append(", lowRamPeriod=");
14018 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14019 Slog.wtfQuiet(TAG, sb.toString());
14020 proc.kill("idle maint (pss " + proc.lastPss
14021 + " from " + proc.initialIdlePss + ")", true);
14024 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14025 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14026 proc.notCachedSinceIdle = true;
14027 proc.initialIdlePss = 0;
14028 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14029 mTestPssMode, isSleepingLocked(), now);
14033 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14034 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14039 public void sendIdleJobTrigger() {
14040 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14041 != PackageManager.PERMISSION_GRANTED) {
14042 throw new SecurityException("Requires permission "
14043 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14046 final long ident = Binder.clearCallingIdentity();
14048 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14049 .setPackage("android")
14050 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14051 broadcastIntent(null, intent, null, null, 0, null, null, null,
14052 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14054 Binder.restoreCallingIdentity(ident);
14058 private void retrieveSettings() {
14059 final ContentResolver resolver = mContext.getContentResolver();
14060 final boolean freeformWindowManagement =
14061 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14062 || Settings.Global.getInt(
14063 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14065 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14066 final boolean supportsPictureInPicture = supportsMultiWindow &&
14067 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14068 final boolean supportsSplitScreenMultiWindow =
14069 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14070 final boolean supportsMultiDisplay = mContext.getPackageManager()
14071 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14072 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14073 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14074 final boolean alwaysFinishActivities =
14075 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14076 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14077 final boolean forceResizable = Settings.Global.getInt(
14078 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14079 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14080 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14081 final boolean supportsLeanbackOnly =
14082 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14084 // Transfer any global setting for forcing RTL layout, into a System Property
14085 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14087 final Configuration configuration = new Configuration();
14088 Settings.System.getConfiguration(resolver, configuration);
14090 // This will take care of setting the correct layout direction flags
14091 configuration.setLayoutDirection(configuration.locale);
14094 synchronized (this) {
14095 mDebugApp = mOrigDebugApp = debugApp;
14096 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14097 mAlwaysFinishActivities = alwaysFinishActivities;
14098 mSupportsLeanbackOnly = supportsLeanbackOnly;
14099 mForceResizableActivities = forceResizable;
14100 final boolean multiWindowFormEnabled = freeformWindowManagement
14101 || supportsSplitScreenMultiWindow
14102 || supportsPictureInPicture
14103 || supportsMultiDisplay;
14104 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14105 mSupportsMultiWindow = true;
14106 mSupportsFreeformWindowManagement = freeformWindowManagement;
14107 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14108 mSupportsPictureInPicture = supportsPictureInPicture;
14109 mSupportsMultiDisplay = supportsMultiDisplay;
14111 mSupportsMultiWindow = false;
14112 mSupportsFreeformWindowManagement = false;
14113 mSupportsSplitScreenMultiWindow = false;
14114 mSupportsPictureInPicture = false;
14115 mSupportsMultiDisplay = false;
14117 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14118 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14119 // This happens before any activities are started, so we can change global configuration
14121 updateConfigurationLocked(configuration, null, true);
14122 final Configuration globalConfig = getGlobalConfiguration();
14123 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14125 // Load resources only after the current configuration has been set.
14126 final Resources res = mContext.getResources();
14127 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14128 mThumbnailWidth = res.getDimensionPixelSize(
14129 com.android.internal.R.dimen.thumbnail_width);
14130 mThumbnailHeight = res.getDimensionPixelSize(
14131 com.android.internal.R.dimen.thumbnail_height);
14132 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14133 com.android.internal.R.string.config_appsNotReportingCrashes));
14134 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14135 com.android.internal.R.bool.config_customUserSwitchUi);
14136 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14137 mFullscreenThumbnailScale = (float) res
14138 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14139 (float) globalConfig.screenWidthDp;
14141 mFullscreenThumbnailScale = res.getFraction(
14142 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14144 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14148 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14149 traceLog.traceBegin("PhaseActivityManagerReady");
14150 synchronized(this) {
14151 if (mSystemReady) {
14152 // If we're done calling all the receivers, run the next "boot phase" passed in
14153 // by the SystemServer
14154 if (goingCallback != null) {
14155 goingCallback.run();
14160 mLocalDeviceIdleController
14161 = LocalServices.getService(DeviceIdleController.LocalService.class);
14162 mAssistUtils = new AssistUtils(mContext);
14163 mVrController.onSystemReady();
14164 // Make sure we have the current profile info, since it is needed for security checks.
14165 mUserController.onSystemReady();
14166 mRecentTasks.onSystemReadyLocked();
14167 mAppOpsService.systemReady();
14168 mSystemReady = true;
14172 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14173 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14175 } catch (RemoteException e) {}
14177 ArrayList<ProcessRecord> procsToKill = null;
14178 synchronized(mPidsSelfLocked) {
14179 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14180 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14181 if (!isAllowedWhileBooting(proc.info)){
14182 if (procsToKill == null) {
14183 procsToKill = new ArrayList<ProcessRecord>();
14185 procsToKill.add(proc);
14190 synchronized(this) {
14191 if (procsToKill != null) {
14192 for (int i=procsToKill.size()-1; i>=0; i--) {
14193 ProcessRecord proc = procsToKill.get(i);
14194 Slog.i(TAG, "Removing system update proc: " + proc);
14195 removeProcessLocked(proc, true, false, "system update done");
14199 // Now that we have cleaned up any update processes, we
14200 // are ready to start launching real processes and know that
14201 // we won't trample on them any more.
14202 mProcessesReady = true;
14205 Slog.i(TAG, "System now ready");
14206 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14207 SystemClock.uptimeMillis());
14209 synchronized(this) {
14210 // Make sure we have no pre-ready processes sitting around.
14212 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14213 ResolveInfo ri = mContext.getPackageManager()
14214 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14216 CharSequence errorMsg = null;
14218 ActivityInfo ai = ri.activityInfo;
14219 ApplicationInfo app = ai.applicationInfo;
14220 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14221 mTopAction = Intent.ACTION_FACTORY_TEST;
14223 mTopComponent = new ComponentName(app.packageName,
14226 errorMsg = mContext.getResources().getText(
14227 com.android.internal.R.string.factorytest_not_system);
14230 errorMsg = mContext.getResources().getText(
14231 com.android.internal.R.string.factorytest_no_action);
14233 if (errorMsg != null) {
14236 mTopComponent = null;
14237 Message msg = Message.obtain();
14238 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14239 msg.getData().putCharSequence("msg", errorMsg);
14240 mUiHandler.sendMessage(msg);
14245 retrieveSettings();
14246 final int currentUserId;
14247 synchronized (this) {
14248 currentUserId = mUserController.getCurrentUserIdLocked();
14249 readGrantedUriPermissionsLocked();
14252 if (goingCallback != null) goingCallback.run();
14253 traceLog.traceBegin("ActivityManagerStartApps");
14254 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14255 Integer.toString(currentUserId), currentUserId);
14256 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14257 Integer.toString(currentUserId), currentUserId);
14258 mSystemServiceManager.startUser(currentUserId);
14260 synchronized (this) {
14261 // Only start up encryption-aware persistent apps; once user is
14262 // unlocked we'll come back around and start unaware apps
14263 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14265 // Start up initial activity.
14267 // Enable home activity for system user, so that the system can always boot. We don't
14268 // do this when the system user is not setup since the setup wizard should be the one
14269 // to handle home activity in this case.
14270 if (UserManager.isSplitSystemUser() &&
14271 Settings.Secure.getInt(mContext.getContentResolver(),
14272 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14273 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14275 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14276 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14277 UserHandle.USER_SYSTEM);
14278 } catch (RemoteException e) {
14279 throw e.rethrowAsRuntimeException();
14282 startHomeActivityLocked(currentUserId, "systemReady");
14285 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14286 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14287 + " data partition or your device will be unstable.");
14288 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14290 } catch (RemoteException e) {
14293 if (!Build.isBuildConsistent()) {
14294 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14295 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14298 long ident = Binder.clearCallingIdentity();
14300 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14301 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14302 | Intent.FLAG_RECEIVER_FOREGROUND);
14303 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14304 broadcastIntentLocked(null, null, intent,
14305 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14306 null, false, false, MY_PID, SYSTEM_UID,
14308 intent = new Intent(Intent.ACTION_USER_STARTING);
14309 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14310 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14311 broadcastIntentLocked(null, null, intent,
14312 null, new IIntentReceiver.Stub() {
14314 public void performReceive(Intent intent, int resultCode, String data,
14315 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14316 throws RemoteException {
14319 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14320 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14321 } catch (Throwable t) {
14322 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14324 Binder.restoreCallingIdentity(ident);
14326 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14327 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14328 traceLog.traceEnd(); // ActivityManagerStartApps
14329 traceLog.traceEnd(); // PhaseActivityManagerReady
14333 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14334 synchronized (this) {
14335 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14339 void skipCurrentReceiverLocked(ProcessRecord app) {
14340 for (BroadcastQueue queue : mBroadcastQueues) {
14341 queue.skipCurrentReceiverLocked(app);
14346 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14347 * The application process will exit immediately after this call returns.
14348 * @param app object of the crashing app, null for the system server
14349 * @param crashInfo describing the exception
14351 public void handleApplicationCrash(IBinder app,
14352 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14353 ProcessRecord r = findAppProcess(app, "Crash");
14354 final String processName = app == null ? "system_server"
14355 : (r == null ? "unknown" : r.processName);
14357 handleApplicationCrashInner("crash", r, processName, crashInfo);
14360 /* Native crash reporting uses this inner version because it needs to be somewhat
14361 * decoupled from the AM-managed cleanup lifecycle
14363 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14364 ApplicationErrorReport.CrashInfo crashInfo) {
14365 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14366 UserHandle.getUserId(Binder.getCallingUid()), processName,
14367 r == null ? -1 : r.info.flags,
14368 crashInfo.exceptionClassName,
14369 crashInfo.exceptionMessage,
14370 crashInfo.throwFileName,
14371 crashInfo.throwLineNumber);
14373 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14375 mAppErrors.crashApplication(r, crashInfo);
14378 public void handleApplicationStrictModeViolation(
14381 StrictMode.ViolationInfo info) {
14382 ProcessRecord r = findAppProcess(app, "StrictMode");
14387 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14388 Integer stackFingerprint = info.hashCode();
14389 boolean logIt = true;
14390 synchronized (mAlreadyLoggedViolatedStacks) {
14391 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14393 // TODO: sub-sample into EventLog for these, with
14394 // the info.durationMillis? Then we'd get
14395 // the relative pain numbers, without logging all
14396 // the stack traces repeatedly. We'd want to do
14397 // likewise in the client code, which also does
14398 // dup suppression, before the Binder call.
14400 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14401 mAlreadyLoggedViolatedStacks.clear();
14403 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14407 logStrictModeViolationToDropBox(r, info);
14411 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14412 AppErrorResult result = new AppErrorResult();
14413 synchronized (this) {
14414 final long origId = Binder.clearCallingIdentity();
14416 Message msg = Message.obtain();
14417 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14418 HashMap<String, Object> data = new HashMap<String, Object>();
14419 data.put("result", result);
14420 data.put("app", r);
14421 data.put("violationMask", violationMask);
14422 data.put("info", info);
14424 mUiHandler.sendMessage(msg);
14426 Binder.restoreCallingIdentity(origId);
14428 int res = result.get();
14429 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14433 // Depending on the policy in effect, there could be a bunch of
14434 // these in quick succession so we try to batch these together to
14435 // minimize disk writes, number of dropbox entries, and maximize
14436 // compression, by having more fewer, larger records.
14437 private void logStrictModeViolationToDropBox(
14438 ProcessRecord process,
14439 StrictMode.ViolationInfo info) {
14440 if (info == null) {
14443 final boolean isSystemApp = process == null ||
14444 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14445 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14446 final String processName = process == null ? "unknown" : process.processName;
14447 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14448 final DropBoxManager dbox = (DropBoxManager)
14449 mContext.getSystemService(Context.DROPBOX_SERVICE);
14451 // Exit early if the dropbox isn't configured to accept this report type.
14452 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14454 boolean bufferWasEmpty;
14455 boolean needsFlush;
14456 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14457 synchronized (sb) {
14458 bufferWasEmpty = sb.length() == 0;
14459 appendDropBoxProcessHeaders(process, processName, sb);
14460 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14461 sb.append("System-App: ").append(isSystemApp).append("\n");
14462 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14463 if (info.violationNumThisLoop != 0) {
14464 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14466 if (info.numAnimationsRunning != 0) {
14467 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14469 if (info.broadcastIntentAction != null) {
14470 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14472 if (info.durationMillis != -1) {
14473 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14475 if (info.numInstances != -1) {
14476 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14478 if (info.tags != null) {
14479 for (String tag : info.tags) {
14480 sb.append("Span-Tag: ").append(tag).append("\n");
14484 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14485 sb.append(info.crashInfo.stackTrace);
14488 if (info.message != null) {
14489 sb.append(info.message);
14493 // Only buffer up to ~64k. Various logging bits truncate
14495 needsFlush = (sb.length() > 64 * 1024);
14498 // Flush immediately if the buffer's grown too large, or this
14499 // is a non-system app. Non-system apps are isolated with a
14500 // different tag & policy and not batched.
14502 // Batching is useful during internal testing with
14503 // StrictMode settings turned up high. Without batching,
14504 // thousands of separate files could be created on boot.
14505 if (!isSystemApp || needsFlush) {
14506 new Thread("Error dump: " + dropboxTag) {
14508 public void run() {
14510 synchronized (sb) {
14511 report = sb.toString();
14512 sb.delete(0, sb.length());
14515 if (report.length() != 0) {
14516 dbox.addText(dropboxTag, report);
14523 // System app batching:
14524 if (!bufferWasEmpty) {
14525 // An existing dropbox-writing thread is outstanding, so
14526 // we don't need to start it up. The existing thread will
14527 // catch the buffer appends we just did.
14531 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14532 // (After this point, we shouldn't access AMS internal data structures.)
14533 new Thread("Error dump: " + dropboxTag) {
14535 public void run() {
14536 // 5 second sleep to let stacks arrive and be batched together
14538 Thread.sleep(5000); // 5 seconds
14539 } catch (InterruptedException e) {}
14541 String errorReport;
14542 synchronized (mStrictModeBuffer) {
14543 errorReport = mStrictModeBuffer.toString();
14544 if (errorReport.length() == 0) {
14547 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14548 mStrictModeBuffer.trimToSize();
14550 dbox.addText(dropboxTag, errorReport);
14556 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14557 * @param app object of the crashing app, null for the system server
14558 * @param tag reported by the caller
14559 * @param system whether this wtf is coming from the system
14560 * @param crashInfo describing the context of the error
14561 * @return true if the process should exit immediately (WTF is fatal)
14563 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14564 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14565 final int callingUid = Binder.getCallingUid();
14566 final int callingPid = Binder.getCallingPid();
14569 // If this is coming from the system, we could very well have low-level
14570 // system locks held, so we want to do this all asynchronously. And we
14571 // never want this to become fatal, so there is that too.
14572 mHandler.post(new Runnable() {
14573 @Override public void run() {
14574 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14580 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14583 final boolean isFatal = Build.IS_ENG || Settings.Global
14584 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14585 final boolean isSystem = (r == null) || r.persistent;
14587 if (isFatal && !isSystem) {
14588 mAppErrors.crashApplication(r, crashInfo);
14595 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14596 final ApplicationErrorReport.CrashInfo crashInfo) {
14597 final ProcessRecord r = findAppProcess(app, "WTF");
14598 final String processName = app == null ? "system_server"
14599 : (r == null ? "unknown" : r.processName);
14601 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14602 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14604 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14610 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14611 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14613 private ProcessRecord findAppProcess(IBinder app, String reason) {
14618 synchronized (this) {
14619 final int NP = mProcessNames.getMap().size();
14620 for (int ip=0; ip<NP; ip++) {
14621 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14622 final int NA = apps.size();
14623 for (int ia=0; ia<NA; ia++) {
14624 ProcessRecord p = apps.valueAt(ia);
14625 if (p.thread != null && p.thread.asBinder() == app) {
14631 Slog.w(TAG, "Can't find mystery application for " + reason
14632 + " from pid=" + Binder.getCallingPid()
14633 + " uid=" + Binder.getCallingUid() + ": " + app);
14639 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14640 * to append various headers to the dropbox log text.
14642 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14643 StringBuilder sb) {
14644 // Watchdog thread ends up invoking this function (with
14645 // a null ProcessRecord) to add the stack file to dropbox.
14646 // Do not acquire a lock on this (am) in such cases, as it
14647 // could cause a potential deadlock, if and when watchdog
14648 // is invoked due to unavailability of lock on am and it
14649 // would prevent watchdog from killing system_server.
14650 if (process == null) {
14651 sb.append("Process: ").append(processName).append("\n");
14654 // Note: ProcessRecord 'process' is guarded by the service
14655 // instance. (notably process.pkgList, which could otherwise change
14656 // concurrently during execution of this method)
14657 synchronized (this) {
14658 sb.append("Process: ").append(processName).append("\n");
14659 sb.append("PID: ").append(process.pid).append("\n");
14660 int flags = process.info.flags;
14661 IPackageManager pm = AppGlobals.getPackageManager();
14662 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14663 for (int ip=0; ip<process.pkgList.size(); ip++) {
14664 String pkg = process.pkgList.keyAt(ip);
14665 sb.append("Package: ").append(pkg);
14667 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14669 sb.append(" v").append(pi.versionCode);
14670 if (pi.versionName != null) {
14671 sb.append(" (").append(pi.versionName).append(")");
14674 } catch (RemoteException e) {
14675 Slog.e(TAG, "Error getting package info: " + pkg, e);
14679 if (process.info.isInstantApp()) {
14680 sb.append("Instant-App: true\n");
14685 private static String processClass(ProcessRecord process) {
14686 if (process == null || process.pid == MY_PID) {
14687 return "system_server";
14688 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14689 return "system_app";
14695 private volatile long mWtfClusterStart;
14696 private volatile int mWtfClusterCount;
14699 * Write a description of an error (crash, WTF, ANR) to the drop box.
14700 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14701 * @param process which caused the error, null means the system server
14702 * @param activity which triggered the error, null if unknown
14703 * @param parent activity related to the error, null if unknown
14704 * @param subject line related to the error, null if absent
14705 * @param report in long form describing the error, null if absent
14706 * @param dataFile text file to include in the report, null if none
14707 * @param crashInfo giving an application stack trace, null if absent
14709 public void addErrorToDropBox(String eventType,
14710 ProcessRecord process, String processName, ActivityRecord activity,
14711 ActivityRecord parent, String subject,
14712 final String report, final File dataFile,
14713 final ApplicationErrorReport.CrashInfo crashInfo) {
14714 // NOTE -- this must never acquire the ActivityManagerService lock,
14715 // otherwise the watchdog may be prevented from resetting the system.
14717 // Bail early if not published yet
14718 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14719 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14721 // Exit early if the dropbox isn't configured to accept this report type.
14722 final String dropboxTag = processClass(process) + "_" + eventType;
14723 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14725 // Rate-limit how often we're willing to do the heavy lifting below to
14726 // collect and record logs; currently 5 logs per 10 second period.
14727 final long now = SystemClock.elapsedRealtime();
14728 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14729 mWtfClusterStart = now;
14730 mWtfClusterCount = 1;
14732 if (mWtfClusterCount++ >= 5) return;
14735 final StringBuilder sb = new StringBuilder(1024);
14736 appendDropBoxProcessHeaders(process, processName, sb);
14737 if (process != null) {
14738 sb.append("Foreground: ")
14739 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14742 if (activity != null) {
14743 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14745 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14746 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14748 if (parent != null && parent != activity) {
14749 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14751 if (subject != null) {
14752 sb.append("Subject: ").append(subject).append("\n");
14754 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14755 if (Debug.isDebuggerConnected()) {
14756 sb.append("Debugger: Connected\n");
14760 // Do the rest in a worker thread to avoid blocking the caller on I/O
14761 // (After this point, we shouldn't access AMS internal data structures.)
14762 Thread worker = new Thread("Error dump: " + dropboxTag) {
14764 public void run() {
14765 if (report != null) {
14769 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14770 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14771 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14772 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14774 if (dataFile != null && maxDataFileSize > 0) {
14776 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14777 "\n\n[[TRUNCATED]]"));
14778 } catch (IOException e) {
14779 Slog.e(TAG, "Error reading " + dataFile, e);
14782 if (crashInfo != null && crashInfo.stackTrace != null) {
14783 sb.append(crashInfo.stackTrace);
14789 // Merge several logcat streams, and take the last N lines
14790 InputStreamReader input = null;
14792 java.lang.Process logcat = new ProcessBuilder(
14793 "/system/bin/timeout", "-k", "15s", "10s",
14794 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14795 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14796 .redirectErrorStream(true).start();
14798 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14799 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14800 input = new InputStreamReader(logcat.getInputStream());
14803 char[] buf = new char[8192];
14804 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14805 } catch (IOException e) {
14806 Slog.e(TAG, "Error running logcat", e);
14808 if (input != null) try { input.close(); } catch (IOException e) {}
14812 dbox.addText(dropboxTag, sb.toString());
14816 if (process == null) {
14817 // If process is null, we are being called from some internal code
14818 // and may be about to die -- run this synchronously.
14826 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14827 enforceNotIsolatedCaller("getProcessesInErrorState");
14828 // assume our apps are happy - lazy create the list
14829 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14831 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14832 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14833 int userId = UserHandle.getUserId(Binder.getCallingUid());
14835 synchronized (this) {
14837 // iterate across all processes
14838 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14839 ProcessRecord app = mLruProcesses.get(i);
14840 if (!allUsers && app.userId != userId) {
14843 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14844 // This one's in trouble, so we'll generate a report for it
14845 // crashes are higher priority (in case there's a crash *and* an anr)
14846 ActivityManager.ProcessErrorStateInfo report = null;
14847 if (app.crashing) {
14848 report = app.crashingReport;
14849 } else if (app.notResponding) {
14850 report = app.notRespondingReport;
14853 if (report != null) {
14854 if (errList == null) {
14855 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14857 errList.add(report);
14859 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14860 " crashing = " + app.crashing +
14861 " notResponding = " + app.notResponding);
14870 static int procStateToImportance(int procState, int memAdj,
14871 ActivityManager.RunningAppProcessInfo currApp,
14872 int clientTargetSdk) {
14873 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14874 procState, clientTargetSdk);
14875 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14876 currApp.lru = memAdj;
14883 private void fillInProcMemInfo(ProcessRecord app,
14884 ActivityManager.RunningAppProcessInfo outInfo,
14885 int clientTargetSdk) {
14886 outInfo.pid = app.pid;
14887 outInfo.uid = app.info.uid;
14888 if (mHeavyWeightProcess == app) {
14889 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14891 if (app.persistent) {
14892 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14894 if (app.activities.size() > 0) {
14895 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14897 outInfo.lastTrimLevel = app.trimMemoryLevel;
14898 int adj = app.curAdj;
14899 int procState = app.curProcState;
14900 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14901 outInfo.importanceReasonCode = app.adjTypeCode;
14902 outInfo.processState = app.curProcState;
14906 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14907 enforceNotIsolatedCaller("getRunningAppProcesses");
14909 final int callingUid = Binder.getCallingUid();
14910 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14912 // Lazy instantiation of list
14913 List<ActivityManager.RunningAppProcessInfo> runList = null;
14914 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14915 callingUid) == PackageManager.PERMISSION_GRANTED;
14916 final int userId = UserHandle.getUserId(callingUid);
14917 final boolean allUids = isGetTasksAllowed(
14918 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14920 synchronized (this) {
14921 // Iterate across all processes
14922 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14923 ProcessRecord app = mLruProcesses.get(i);
14924 if ((!allUsers && app.userId != userId)
14925 || (!allUids && app.uid != callingUid)) {
14928 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14929 // Generate process state info for running application
14930 ActivityManager.RunningAppProcessInfo currApp =
14931 new ActivityManager.RunningAppProcessInfo(app.processName,
14932 app.pid, app.getPackageList());
14933 fillInProcMemInfo(app, currApp, clientTargetSdk);
14934 if (app.adjSource instanceof ProcessRecord) {
14935 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14936 currApp.importanceReasonImportance =
14937 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14938 app.adjSourceProcState);
14939 } else if (app.adjSource instanceof ActivityRecord) {
14940 ActivityRecord r = (ActivityRecord)app.adjSource;
14941 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14943 if (app.adjTarget instanceof ComponentName) {
14944 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14946 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14947 // + " lru=" + currApp.lru);
14948 if (runList == null) {
14949 runList = new ArrayList<>();
14951 runList.add(currApp);
14959 public List<ApplicationInfo> getRunningExternalApplications() {
14960 enforceNotIsolatedCaller("getRunningExternalApplications");
14961 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14962 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14963 if (runningApps != null && runningApps.size() > 0) {
14964 Set<String> extList = new HashSet<String>();
14965 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14966 if (app.pkgList != null) {
14967 for (String pkg : app.pkgList) {
14972 IPackageManager pm = AppGlobals.getPackageManager();
14973 for (String pkg : extList) {
14975 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14976 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14979 } catch (RemoteException e) {
14987 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14988 enforceNotIsolatedCaller("getMyMemoryState");
14990 final int callingUid = Binder.getCallingUid();
14991 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14993 synchronized (this) {
14994 ProcessRecord proc;
14995 synchronized (mPidsSelfLocked) {
14996 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14998 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15003 public int getMemoryTrimLevel() {
15004 enforceNotIsolatedCaller("getMyMemoryState");
15005 synchronized (this) {
15006 return mLastMemoryLevel;
15011 public void onShellCommand(FileDescriptor in, FileDescriptor out,
15012 FileDescriptor err, String[] args, ShellCallback callback,
15013 ResultReceiver resultReceiver) {
15014 (new ActivityManagerShellCommand(this, false)).exec(
15015 this, in, out, err, args, callback, resultReceiver);
15018 SleepToken acquireSleepToken(String tag, int displayId) {
15019 synchronized (this) {
15020 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15021 updateSleepIfNeededLocked();
15027 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15028 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15030 boolean dumpAll = false;
15031 boolean dumpClient = false;
15032 boolean dumpCheckin = false;
15033 boolean dumpCheckinFormat = false;
15034 boolean dumpVisibleStacksOnly = false;
15035 boolean dumpFocusedStackOnly = false;
15036 String dumpPackage = null;
15039 while (opti < args.length) {
15040 String opt = args[opti];
15041 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15045 if ("-a".equals(opt)) {
15047 } else if ("-c".equals(opt)) {
15049 } else if ("-v".equals(opt)) {
15050 dumpVisibleStacksOnly = true;
15051 } else if ("-f".equals(opt)) {
15052 dumpFocusedStackOnly = true;
15053 } else if ("-p".equals(opt)) {
15054 if (opti < args.length) {
15055 dumpPackage = args[opti];
15058 pw.println("Error: -p option requires package argument");
15062 } else if ("--checkin".equals(opt)) {
15063 dumpCheckin = dumpCheckinFormat = true;
15064 } else if ("-C".equals(opt)) {
15065 dumpCheckinFormat = true;
15066 } else if ("-h".equals(opt)) {
15067 ActivityManagerShellCommand.dumpHelp(pw, true);
15070 pw.println("Unknown argument: " + opt + "; use -h for help");
15074 long origId = Binder.clearCallingIdentity();
15075 boolean more = false;
15076 // Is the caller requesting to dump a particular piece of data?
15077 if (opti < args.length) {
15078 String cmd = args[opti];
15080 if ("activities".equals(cmd) || "a".equals(cmd)) {
15081 synchronized (this) {
15082 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15084 } else if ("lastanr".equals(cmd)) {
15085 synchronized (this) {
15086 dumpLastANRLocked(pw);
15088 } else if ("starter".equals(cmd)) {
15089 synchronized (this) {
15090 dumpActivityStarterLocked(pw, dumpPackage);
15092 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15093 synchronized (this) {
15094 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15096 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15099 if (opti >= args.length) {
15101 newArgs = EMPTY_STRING_ARRAY;
15103 dumpPackage = args[opti];
15105 newArgs = new String[args.length - opti];
15106 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15107 args.length - opti);
15109 synchronized (this) {
15110 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15112 } else if ("broadcast-stats".equals(cmd)) {
15115 if (opti >= args.length) {
15117 newArgs = EMPTY_STRING_ARRAY;
15119 dumpPackage = args[opti];
15121 newArgs = new String[args.length - opti];
15122 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15123 args.length - opti);
15125 synchronized (this) {
15126 if (dumpCheckinFormat) {
15127 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15130 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15133 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15136 if (opti >= args.length) {
15138 newArgs = EMPTY_STRING_ARRAY;
15140 dumpPackage = args[opti];
15142 newArgs = new String[args.length - opti];
15143 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15144 args.length - opti);
15146 synchronized (this) {
15147 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15149 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15152 if (opti >= args.length) {
15154 newArgs = EMPTY_STRING_ARRAY;
15156 dumpPackage = args[opti];
15158 newArgs = new String[args.length - opti];
15159 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15160 args.length - opti);
15162 synchronized (this) {
15163 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15165 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15166 synchronized (this) {
15167 dumpOomLocked(fd, pw, args, opti, true);
15169 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15170 synchronized (this) {
15171 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15173 } else if ("provider".equals(cmd)) {
15176 if (opti >= args.length) {
15178 newArgs = EMPTY_STRING_ARRAY;
15182 newArgs = new String[args.length - opti];
15183 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15185 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15186 pw.println("No providers match: " + name);
15187 pw.println("Use -h for help.");
15189 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15190 synchronized (this) {
15191 dumpProvidersLocked(fd, pw, args, opti, true, null);
15193 } else if ("service".equals(cmd)) {
15196 if (opti >= args.length) {
15198 newArgs = EMPTY_STRING_ARRAY;
15202 newArgs = new String[args.length - opti];
15203 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15204 args.length - opti);
15206 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15207 pw.println("No services match: " + name);
15208 pw.println("Use -h for help.");
15210 } else if ("package".equals(cmd)) {
15212 if (opti >= args.length) {
15213 pw.println("package: no package name specified");
15214 pw.println("Use -h for help.");
15216 dumpPackage = args[opti];
15218 newArgs = new String[args.length - opti];
15219 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15220 args.length - opti);
15225 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15226 synchronized (this) {
15227 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15229 } else if ("settings".equals(cmd)) {
15230 synchronized (this) {
15231 mConstants.dump(pw);
15233 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15235 ActiveServices.ServiceDumper dumper;
15236 synchronized (this) {
15237 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15240 dumper.dumpWithClient();
15242 synchronized (this) {
15243 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15244 dumpPackage).dumpLocked();
15247 } else if ("locks".equals(cmd)) {
15248 LockGuard.dump(fd, pw, args);
15250 // Dumping a single activity?
15251 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15252 dumpFocusedStackOnly)) {
15253 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15254 int res = shell.exec(this, null, fd, null, args, null,
15255 new ResultReceiver(null));
15257 pw.println("Bad activity command, or no activities match: " + cmd);
15258 pw.println("Use -h for help.");
15263 Binder.restoreCallingIdentity(origId);
15268 // No piece of data specified, dump everything.
15269 if (dumpCheckinFormat) {
15270 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15271 } else if (dumpClient) {
15272 ActiveServices.ServiceDumper sdumper;
15273 synchronized (this) {
15274 mConstants.dump(pw);
15277 pw.println("-------------------------------------------------------------------------------");
15279 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15282 pw.println("-------------------------------------------------------------------------------");
15284 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15287 pw.println("-------------------------------------------------------------------------------");
15289 if (dumpAll || dumpPackage != null) {
15290 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15293 pw.println("-------------------------------------------------------------------------------");
15296 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15299 pw.println("-------------------------------------------------------------------------------");
15301 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15304 pw.println("-------------------------------------------------------------------------------");
15306 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15309 sdumper.dumpWithClient();
15311 synchronized (this) {
15313 pw.println("-------------------------------------------------------------------------------");
15315 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15318 pw.println("-------------------------------------------------------------------------------");
15320 dumpLastANRLocked(pw);
15323 pw.println("-------------------------------------------------------------------------------");
15325 dumpActivityStarterLocked(pw, dumpPackage);
15328 pw.println("-------------------------------------------------------------------------------");
15330 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15331 if (mAssociations.size() > 0) {
15334 pw.println("-------------------------------------------------------------------------------");
15336 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15340 pw.println("-------------------------------------------------------------------------------");
15342 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15346 synchronized (this) {
15347 mConstants.dump(pw);
15350 pw.println("-------------------------------------------------------------------------------");
15352 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15355 pw.println("-------------------------------------------------------------------------------");
15357 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15360 pw.println("-------------------------------------------------------------------------------");
15362 if (dumpAll || dumpPackage != null) {
15363 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15366 pw.println("-------------------------------------------------------------------------------");
15369 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15372 pw.println("-------------------------------------------------------------------------------");
15374 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15377 pw.println("-------------------------------------------------------------------------------");
15379 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15383 pw.println("-------------------------------------------------------------------------------");
15385 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15388 pw.println("-------------------------------------------------------------------------------");
15390 dumpLastANRLocked(pw);
15393 pw.println("-------------------------------------------------------------------------------");
15395 dumpActivityStarterLocked(pw, dumpPackage);
15398 pw.println("-------------------------------------------------------------------------------");
15400 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15401 if (mAssociations.size() > 0) {
15404 pw.println("-------------------------------------------------------------------------------");
15406 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15410 pw.println("-------------------------------------------------------------------------------");
15412 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15415 Binder.restoreCallingIdentity(origId);
15418 private void dumpLastANRLocked(PrintWriter pw) {
15419 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15420 if (mLastANRState == null) {
15421 pw.println(" <no ANR has occurred since boot>");
15423 pw.println(mLastANRState);
15427 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15428 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15429 mActivityStarter.dump(pw, "", dumpPackage);
15432 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15433 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15434 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15435 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15438 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15439 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15440 pw.println(header);
15442 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15444 boolean needSep = printedAnything;
15446 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15447 mStackSupervisor.getResumedActivityLocked(),
15448 dumpPackage, needSep, " ResumedActivity: ");
15450 printedAnything = true;
15454 if (dumpPackage == null) {
15458 printedAnything = true;
15459 mStackSupervisor.dump(pw, " ");
15462 if (!printedAnything) {
15463 pw.println(" (nothing)");
15467 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15468 int opti, boolean dumpAll, String dumpPackage) {
15469 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15471 boolean printedAnything = false;
15473 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15474 boolean printedHeader = false;
15476 final int N = mRecentTasks.size();
15477 for (int i=0; i<N; i++) {
15478 TaskRecord tr = mRecentTasks.get(i);
15479 if (dumpPackage != null) {
15480 if (tr.realActivity == null ||
15481 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15485 if (!printedHeader) {
15486 pw.println(" Recent tasks:");
15487 printedHeader = true;
15488 printedAnything = true;
15490 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15493 mRecentTasks.get(i).dump(pw, " ");
15498 if (!printedAnything) {
15499 pw.println(" (nothing)");
15503 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15504 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15505 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15508 if (dumpPackage != null) {
15509 IPackageManager pm = AppGlobals.getPackageManager();
15511 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15512 } catch (RemoteException e) {
15516 boolean printedAnything = false;
15518 final long now = SystemClock.uptimeMillis();
15520 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15521 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15522 = mAssociations.valueAt(i1);
15523 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15524 SparseArray<ArrayMap<String, Association>> sourceUids
15525 = targetComponents.valueAt(i2);
15526 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15527 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15528 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15529 Association ass = sourceProcesses.valueAt(i4);
15530 if (dumpPackage != null) {
15531 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15532 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15536 printedAnything = true;
15538 pw.print(ass.mTargetProcess);
15540 UserHandle.formatUid(pw, ass.mTargetUid);
15542 pw.print(ass.mSourceProcess);
15544 UserHandle.formatUid(pw, ass.mSourceUid);
15547 pw.print(ass.mTargetComponent.flattenToShortString());
15550 long dur = ass.mTime;
15551 if (ass.mNesting > 0) {
15552 dur += now - ass.mStartTime;
15554 TimeUtils.formatDuration(dur, pw);
15556 pw.print(ass.mCount);
15557 pw.print(" times)");
15559 for (int i=0; i<ass.mStateTimes.length; i++) {
15560 long amt = ass.mStateTimes[i];
15561 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15562 amt += now - ass.mLastStateUptime;
15566 pw.print(ProcessList.makeProcStateString(
15567 i + ActivityManager.MIN_PROCESS_STATE));
15569 TimeUtils.formatDuration(amt, pw);
15570 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15576 if (ass.mNesting > 0) {
15577 pw.print(" Currently active: ");
15578 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15587 if (!printedAnything) {
15588 pw.println(" (nothing)");
15592 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15593 String header, boolean needSep) {
15594 boolean printed = false;
15595 int whichAppId = -1;
15596 if (dumpPackage != null) {
15598 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15600 whichAppId = UserHandle.getAppId(info.uid);
15601 } catch (NameNotFoundException e) {
15602 e.printStackTrace();
15605 for (int i=0; i<uids.size(); i++) {
15606 UidRecord uidRec = uids.valueAt(i);
15607 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15616 pw.println(header);
15619 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15620 pw.print(": "); pw.println(uidRec);
15625 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15626 int opti, boolean dumpAll, String dumpPackage) {
15627 boolean needSep = false;
15628 boolean printedAnything = false;
15631 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15634 final int NP = mProcessNames.getMap().size();
15635 for (int ip=0; ip<NP; ip++) {
15636 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15637 final int NA = procs.size();
15638 for (int ia=0; ia<NA; ia++) {
15639 ProcessRecord r = procs.valueAt(ia);
15640 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15644 pw.println(" All known processes:");
15646 printedAnything = true;
15648 pw.print(r.persistent ? " *PERS*" : " *APP*");
15649 pw.print(" UID "); pw.print(procs.keyAt(ia));
15650 pw.print(" "); pw.println(r);
15652 if (r.persistent) {
15659 if (mIsolatedProcesses.size() > 0) {
15660 boolean printed = false;
15661 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15662 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15663 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15670 pw.println(" Isolated process list (sorted by uid):");
15671 printedAnything = true;
15675 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15680 if (mActiveInstrumentation.size() > 0) {
15681 boolean printed = false;
15682 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15683 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15684 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15685 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15692 pw.println(" Active instrumentation:");
15693 printedAnything = true;
15697 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15703 if (mActiveUids.size() > 0) {
15704 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15705 printedAnything = needSep = true;
15709 if (mValidateUids.size() > 0) {
15710 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15711 printedAnything = needSep = true;
15716 if (mLruProcesses.size() > 0) {
15720 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15721 pw.print(" total, non-act at ");
15722 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15723 pw.print(", non-svc at ");
15724 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15726 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15728 printedAnything = true;
15731 if (dumpAll || dumpPackage != null) {
15732 synchronized (mPidsSelfLocked) {
15733 boolean printed = false;
15734 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15735 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15736 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15740 if (needSep) pw.println();
15742 pw.println(" PID mappings:");
15744 printedAnything = true;
15746 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15747 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15752 if (mImportantProcesses.size() > 0) {
15753 synchronized (mPidsSelfLocked) {
15754 boolean printed = false;
15755 for (int i = 0; i< mImportantProcesses.size(); i++) {
15756 ProcessRecord r = mPidsSelfLocked.get(
15757 mImportantProcesses.valueAt(i).pid);
15758 if (dumpPackage != null && (r == null
15759 || !r.pkgList.containsKey(dumpPackage))) {
15763 if (needSep) pw.println();
15765 pw.println(" Foreground Processes:");
15767 printedAnything = true;
15769 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15770 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15775 if (mPersistentStartingProcesses.size() > 0) {
15776 if (needSep) pw.println();
15778 printedAnything = true;
15779 pw.println(" Persisent processes that are starting:");
15780 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15781 "Starting Norm", "Restarting PERS", dumpPackage);
15784 if (mRemovedProcesses.size() > 0) {
15785 if (needSep) pw.println();
15787 printedAnything = true;
15788 pw.println(" Processes that are being removed:");
15789 dumpProcessList(pw, this, mRemovedProcesses, " ",
15790 "Removed Norm", "Removed PERS", dumpPackage);
15793 if (mProcessesOnHold.size() > 0) {
15794 if (needSep) pw.println();
15796 printedAnything = true;
15797 pw.println(" Processes that are on old until the system is ready:");
15798 dumpProcessList(pw, this, mProcessesOnHold, " ",
15799 "OnHold Norm", "OnHold PERS", dumpPackage);
15802 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15804 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15806 printedAnything = true;
15809 if (dumpPackage == null) {
15812 mUserController.dump(pw, dumpAll);
15814 if (mHomeProcess != null && (dumpPackage == null
15815 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15820 pw.println(" mHomeProcess: " + mHomeProcess);
15822 if (mPreviousProcess != null && (dumpPackage == null
15823 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15828 pw.println(" mPreviousProcess: " + mPreviousProcess);
15831 StringBuilder sb = new StringBuilder(128);
15832 sb.append(" mPreviousProcessVisibleTime: ");
15833 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15836 if (mHeavyWeightProcess != null && (dumpPackage == null
15837 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15842 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15844 if (dumpPackage == null) {
15845 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15846 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15849 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15850 if (mCompatModePackages.getPackages().size() > 0) {
15851 boolean printed = false;
15852 for (Map.Entry<String, Integer> entry
15853 : mCompatModePackages.getPackages().entrySet()) {
15854 String pkg = entry.getKey();
15855 int mode = entry.getValue();
15856 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15860 pw.println(" mScreenCompatPackages:");
15863 pw.print(" "); pw.print(pkg); pw.print(": ");
15864 pw.print(mode); pw.println();
15867 final int NI = mUidObservers.getRegisteredCallbackCount();
15868 boolean printed = false;
15869 for (int i=0; i<NI; i++) {
15870 final UidObserverRegistration reg = (UidObserverRegistration)
15871 mUidObservers.getRegisteredCallbackCookie(i);
15872 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15874 pw.println(" mUidObservers:");
15877 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15878 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15879 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15882 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15885 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15888 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15889 pw.print(" STATE");
15890 pw.print(" (cut="); pw.print(reg.cutpoint);
15894 if (reg.lastProcStates != null) {
15895 final int NJ = reg.lastProcStates.size();
15896 for (int j=0; j<NJ; j++) {
15897 pw.print(" Last ");
15898 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15899 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15904 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15905 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15906 if (mPendingTempWhitelist.size() > 0) {
15907 pw.println(" mPendingTempWhitelist:");
15908 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15909 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15911 UserHandle.formatUid(pw, ptw.targetUid);
15913 TimeUtils.formatDuration(ptw.duration, pw);
15915 pw.println(ptw.tag);
15919 if (dumpPackage == null) {
15920 pw.println(" mWakefulness="
15921 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15922 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
15923 pw.println(" mSleeping=" + mSleeping);
15924 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15925 if (mRunningVoice != null) {
15926 pw.println(" mRunningVoice=" + mRunningVoice);
15927 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15930 pw.println(" mVrController=" + mVrController);
15931 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15932 || mOrigWaitForDebugger) {
15933 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15934 || dumpPackage.equals(mOrigDebugApp)) {
15939 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15940 + " mDebugTransient=" + mDebugTransient
15941 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15944 if (mCurAppTimeTracker != null) {
15945 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15947 if (mMemWatchProcesses.getMap().size() > 0) {
15948 pw.println(" Mem watch processes:");
15949 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15950 = mMemWatchProcesses.getMap();
15951 for (int i=0; i<procs.size(); i++) {
15952 final String proc = procs.keyAt(i);
15953 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15954 for (int j=0; j<uids.size(); j++) {
15959 StringBuilder sb = new StringBuilder();
15960 sb.append(" ").append(proc).append('/');
15961 UserHandle.formatUid(sb, uids.keyAt(j));
15962 Pair<Long, String> val = uids.valueAt(j);
15963 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15964 if (val.second != null) {
15965 sb.append(", report to ").append(val.second);
15967 pw.println(sb.toString());
15970 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15971 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15972 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15973 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15975 if (mTrackAllocationApp != null) {
15976 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15981 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15984 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15985 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15986 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15991 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15992 if (mProfilerInfo != null) {
15993 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
15994 mProfilerInfo.profileFd);
15995 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
15996 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
15997 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
15998 pw.println(" mProfileType=" + mProfileType);
16002 if (mNativeDebuggingApp != null) {
16003 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16008 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
16011 if (dumpPackage == null) {
16012 if (mAlwaysFinishActivities) {
16013 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16015 if (mController != null) {
16016 pw.println(" mController=" + mController
16017 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16020 pw.println(" Total persistent processes: " + numPers);
16021 pw.println(" mProcessesReady=" + mProcessesReady
16022 + " mSystemReady=" + mSystemReady
16023 + " mBooted=" + mBooted
16024 + " mFactoryTest=" + mFactoryTest);
16025 pw.println(" mBooting=" + mBooting
16026 + " mCallFinishBooting=" + mCallFinishBooting
16027 + " mBootAnimationComplete=" + mBootAnimationComplete);
16028 pw.print(" mLastPowerCheckUptime=");
16029 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16031 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16032 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16033 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16034 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
16035 + " (" + mLruProcesses.size() + " total)"
16036 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16037 + " mNumServiceProcs=" + mNumServiceProcs
16038 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16039 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
16040 + " mLastMemoryLevel=" + mLastMemoryLevel
16041 + " mLastNumProcesses=" + mLastNumProcesses);
16042 long now = SystemClock.uptimeMillis();
16043 pw.print(" mLastIdleTime=");
16044 TimeUtils.formatDuration(now, mLastIdleTime, pw);
16045 pw.print(" mLowRamSinceLastIdle=");
16046 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16051 if (!printedAnything) {
16052 pw.println(" (nothing)");
16056 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16057 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16058 if (mProcessesToGc.size() > 0) {
16059 boolean printed = false;
16060 long now = SystemClock.uptimeMillis();
16061 for (int i=0; i<mProcessesToGc.size(); i++) {
16062 ProcessRecord proc = mProcessesToGc.get(i);
16063 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16067 if (needSep) pw.println();
16069 pw.println(" Processes that are waiting to GC:");
16072 pw.print(" Process "); pw.println(proc);
16073 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16074 pw.print(", last gced=");
16075 pw.print(now-proc.lastRequestedGc);
16076 pw.print(" ms ago, last lowMem=");
16077 pw.print(now-proc.lastLowMemory);
16078 pw.println(" ms ago");
16085 void printOomLevel(PrintWriter pw, String name, int adj) {
16089 if (adj < 10) pw.print(' ');
16091 if (adj > -10) pw.print(' ');
16097 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16101 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16102 int opti, boolean dumpAll) {
16103 boolean needSep = false;
16105 if (mLruProcesses.size() > 0) {
16106 if (needSep) pw.println();
16108 pw.println(" OOM levels:");
16109 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16110 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16111 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16112 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16113 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16114 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16115 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16116 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16117 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16118 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16119 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16120 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16121 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16122 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16124 if (needSep) pw.println();
16125 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16126 pw.print(" total, non-act at ");
16127 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16128 pw.print(", non-svc at ");
16129 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16131 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16135 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16138 pw.println(" mHomeProcess: " + mHomeProcess);
16139 pw.println(" mPreviousProcess: " + mPreviousProcess);
16140 if (mHeavyWeightProcess != null) {
16141 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16148 * There are three ways to call this:
16149 * - no provider specified: dump all the providers
16150 * - a flattened component name that matched an existing provider was specified as the
16151 * first arg: dump that one provider
16152 * - the first arg isn't the flattened component name of an existing provider:
16153 * dump all providers whose component contains the first arg as a substring
16155 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16156 int opti, boolean dumpAll) {
16157 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16160 static class ItemMatcher {
16161 ArrayList<ComponentName> components;
16162 ArrayList<String> strings;
16163 ArrayList<Integer> objects;
16170 void build(String name) {
16171 ComponentName componentName = ComponentName.unflattenFromString(name);
16172 if (componentName != null) {
16173 if (components == null) {
16174 components = new ArrayList<ComponentName>();
16176 components.add(componentName);
16180 // Not a '/' separated full component name; maybe an object ID?
16182 objectId = Integer.parseInt(name, 16);
16183 if (objects == null) {
16184 objects = new ArrayList<Integer>();
16186 objects.add(objectId);
16188 } catch (RuntimeException e) {
16189 // Not an integer; just do string match.
16190 if (strings == null) {
16191 strings = new ArrayList<String>();
16199 int build(String[] args, int opti) {
16200 for (; opti<args.length; opti++) {
16201 String name = args[opti];
16202 if ("--".equals(name)) {
16210 boolean match(Object object, ComponentName comp) {
16214 if (components != null) {
16215 for (int i=0; i<components.size(); i++) {
16216 if (components.get(i).equals(comp)) {
16221 if (objects != null) {
16222 for (int i=0; i<objects.size(); i++) {
16223 if (System.identityHashCode(object) == objects.get(i)) {
16228 if (strings != null) {
16229 String flat = comp.flattenToString();
16230 for (int i=0; i<strings.size(); i++) {
16231 if (flat.contains(strings.get(i))) {
16241 * There are three things that cmd can be:
16242 * - a flattened component name that matches an existing activity
16243 * - the cmd arg isn't the flattened component name of an existing activity:
16244 * dump all activity whose component contains the cmd as a substring
16245 * - A hex number of the ActivityRecord object instance.
16247 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16248 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16250 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16251 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16252 ArrayList<ActivityRecord> activities;
16254 synchronized (this) {
16255 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16256 dumpFocusedStackOnly);
16259 if (activities.size() <= 0) {
16263 String[] newArgs = new String[args.length - opti];
16264 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16266 TaskRecord lastTask = null;
16267 boolean needSep = false;
16268 for (int i=activities.size()-1; i>=0; i--) {
16269 ActivityRecord r = activities.get(i);
16274 synchronized (this) {
16275 final TaskRecord task = r.getTask();
16276 if (lastTask != task) {
16278 pw.print("TASK "); pw.print(lastTask.affinity);
16279 pw.print(" id="); pw.print(lastTask.taskId);
16280 pw.print(" userId="); pw.println(lastTask.userId);
16282 lastTask.dump(pw, " ");
16286 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16292 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16293 * there is a thread associated with the activity.
16295 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16296 final ActivityRecord r, String[] args, boolean dumpAll) {
16297 String innerPrefix = prefix + " ";
16298 synchronized (this) {
16299 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16300 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16302 if (r.app != null) pw.println(r.app.pid);
16303 else pw.println("(not running)");
16305 r.dump(pw, innerPrefix);
16308 if (r.app != null && r.app.thread != null) {
16309 // flush anything that is already in the PrintWriter since the thread is going
16310 // to write to the file descriptor directly
16313 TransferPipe tp = new TransferPipe();
16315 r.app.thread.dumpActivity(tp.getWriteFd(),
16316 r.appToken, innerPrefix, args);
16321 } catch (IOException e) {
16322 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16323 } catch (RemoteException e) {
16324 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16329 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16330 int opti, boolean dumpAll, String dumpPackage) {
16331 boolean needSep = false;
16332 boolean onlyHistory = false;
16333 boolean printedAnything = false;
16335 if ("history".equals(dumpPackage)) {
16336 if (opti < args.length && "-s".equals(args[opti])) {
16339 onlyHistory = true;
16340 dumpPackage = null;
16343 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16344 if (!onlyHistory && dumpAll) {
16345 if (mRegisteredReceivers.size() > 0) {
16346 boolean printed = false;
16347 Iterator it = mRegisteredReceivers.values().iterator();
16348 while (it.hasNext()) {
16349 ReceiverList r = (ReceiverList)it.next();
16350 if (dumpPackage != null && (r.app == null ||
16351 !dumpPackage.equals(r.app.info.packageName))) {
16355 pw.println(" Registered Receivers:");
16358 printedAnything = true;
16360 pw.print(" * "); pw.println(r);
16365 if (mReceiverResolver.dump(pw, needSep ?
16366 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16367 " ", dumpPackage, false, false)) {
16369 printedAnything = true;
16373 for (BroadcastQueue q : mBroadcastQueues) {
16374 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16375 printedAnything |= needSep;
16380 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16381 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16386 printedAnything = true;
16387 pw.print(" Sticky broadcasts for user ");
16388 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16389 StringBuilder sb = new StringBuilder(128);
16390 for (Map.Entry<String, ArrayList<Intent>> ent
16391 : mStickyBroadcasts.valueAt(user).entrySet()) {
16392 pw.print(" * Sticky action "); pw.print(ent.getKey());
16395 ArrayList<Intent> intents = ent.getValue();
16396 final int N = intents.size();
16397 for (int i=0; i<N; i++) {
16399 sb.append(" Intent: ");
16400 intents.get(i).toShortString(sb, false, true, false, false);
16401 pw.println(sb.toString());
16402 Bundle bundle = intents.get(i).getExtras();
16403 if (bundle != null) {
16405 pw.println(bundle.toString());
16415 if (!onlyHistory && dumpAll) {
16417 for (BroadcastQueue queue : mBroadcastQueues) {
16418 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16419 + queue.mBroadcastsScheduled);
16421 pw.println(" mHandler:");
16422 mHandler.dump(new PrintWriterPrinter(pw), " ");
16424 printedAnything = true;
16427 if (!printedAnything) {
16428 pw.println(" (nothing)");
16432 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16433 int opti, boolean dumpAll, String dumpPackage) {
16434 if (mCurBroadcastStats == null) {
16438 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16439 final long now = SystemClock.elapsedRealtime();
16440 if (mLastBroadcastStats != null) {
16441 pw.print(" Last stats (from ");
16442 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16444 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16446 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16447 - mLastBroadcastStats.mStartUptime, pw);
16448 pw.println(" uptime):");
16449 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16450 pw.println(" (nothing)");
16454 pw.print(" Current stats (from ");
16455 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16456 pw.print(" to now, ");
16457 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16458 - mCurBroadcastStats.mStartUptime, pw);
16459 pw.println(" uptime):");
16460 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16461 pw.println(" (nothing)");
16465 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16466 int opti, boolean fullCheckin, String dumpPackage) {
16467 if (mCurBroadcastStats == null) {
16471 if (mLastBroadcastStats != null) {
16472 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16474 mLastBroadcastStats = null;
16478 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16480 mCurBroadcastStats = null;
16484 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16485 int opti, boolean dumpAll, String dumpPackage) {
16487 boolean printedAnything = false;
16489 ItemMatcher matcher = new ItemMatcher();
16490 matcher.build(args, opti);
16492 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16494 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16495 printedAnything |= needSep;
16497 if (mLaunchingProviders.size() > 0) {
16498 boolean printed = false;
16499 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16500 ContentProviderRecord r = mLaunchingProviders.get(i);
16501 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16505 if (needSep) pw.println();
16507 pw.println(" Launching content providers:");
16509 printedAnything = true;
16511 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16516 if (!printedAnything) {
16517 pw.println(" (nothing)");
16521 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16522 int opti, boolean dumpAll, String dumpPackage) {
16523 boolean needSep = false;
16524 boolean printedAnything = false;
16526 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16528 if (mGrantedUriPermissions.size() > 0) {
16529 boolean printed = false;
16531 if (dumpPackage != null) {
16533 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16534 MATCH_ANY_USER, 0);
16535 } catch (NameNotFoundException e) {
16539 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16540 int uid = mGrantedUriPermissions.keyAt(i);
16541 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16544 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16546 if (needSep) pw.println();
16548 pw.println(" Granted Uri Permissions:");
16550 printedAnything = true;
16552 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16553 for (UriPermission perm : perms.values()) {
16554 pw.print(" "); pw.println(perm);
16556 perm.dump(pw, " ");
16562 if (!printedAnything) {
16563 pw.println(" (nothing)");
16567 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16568 int opti, boolean dumpAll, String dumpPackage) {
16569 boolean printed = false;
16571 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16573 if (mIntentSenderRecords.size() > 0) {
16574 // Organize these by package name, so they are easier to read.
16575 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16576 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16577 final Iterator<WeakReference<PendingIntentRecord>> it
16578 = mIntentSenderRecords.values().iterator();
16579 while (it.hasNext()) {
16580 WeakReference<PendingIntentRecord> ref = it.next();
16581 PendingIntentRecord rec = ref != null ? ref.get() : null;
16586 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16589 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16590 if (list == null) {
16591 list = new ArrayList<>();
16592 byPackage.put(rec.key.packageName, list);
16596 for (int i = 0; i < byPackage.size(); i++) {
16597 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16599 pw.print(" * "); pw.print(byPackage.keyAt(i));
16600 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16601 for (int j = 0; j < intents.size(); j++) {
16602 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16604 intents.get(j).dump(pw, " ");
16608 if (weakRefs.size() > 0) {
16610 pw.println(" * WEAK REFS:");
16611 for (int i = 0; i < weakRefs.size(); i++) {
16612 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16618 pw.println(" (nothing)");
16622 private static final int dumpProcessList(PrintWriter pw,
16623 ActivityManagerService service, List list,
16624 String prefix, String normalLabel, String persistentLabel,
16625 String dumpPackage) {
16627 final int N = list.size()-1;
16628 for (int i=N; i>=0; i--) {
16629 ProcessRecord r = (ProcessRecord)list.get(i);
16630 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16633 pw.println(String.format("%s%s #%2d: %s",
16634 prefix, (r.persistent ? persistentLabel : normalLabel),
16636 if (r.persistent) {
16643 private static final boolean dumpProcessOomList(PrintWriter pw,
16644 ActivityManagerService service, List<ProcessRecord> origList,
16645 String prefix, String normalLabel, String persistentLabel,
16646 boolean inclDetails, String dumpPackage) {
16648 ArrayList<Pair<ProcessRecord, Integer>> list
16649 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16650 for (int i=0; i<origList.size(); i++) {
16651 ProcessRecord r = origList.get(i);
16652 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16655 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16658 if (list.size() <= 0) {
16662 Comparator<Pair<ProcessRecord, Integer>> comparator
16663 = new Comparator<Pair<ProcessRecord, Integer>>() {
16665 public int compare(Pair<ProcessRecord, Integer> object1,
16666 Pair<ProcessRecord, Integer> object2) {
16667 if (object1.first.setAdj != object2.first.setAdj) {
16668 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16670 if (object1.first.setProcState != object2.first.setProcState) {
16671 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16673 if (object1.second.intValue() != object2.second.intValue()) {
16674 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16680 Collections.sort(list, comparator);
16682 final long curUptime = SystemClock.uptimeMillis();
16683 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16685 for (int i=list.size()-1; i>=0; i--) {
16686 ProcessRecord r = list.get(i).first;
16687 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16689 switch (r.setSchedGroup) {
16690 case ProcessList.SCHED_GROUP_BACKGROUND:
16693 case ProcessList.SCHED_GROUP_DEFAULT:
16696 case ProcessList.SCHED_GROUP_TOP_APP:
16704 if (r.foregroundActivities) {
16706 } else if (r.foregroundServices) {
16711 String procState = ProcessList.makeProcStateString(r.curProcState);
16713 pw.print(r.persistent ? persistentLabel : normalLabel);
16715 int num = (origList.size()-1)-list.get(i).second;
16716 if (num < 10) pw.print(' ');
16721 pw.print(schedGroup);
16723 pw.print(foreground);
16725 pw.print(procState);
16727 if (r.trimMemoryLevel < 10) pw.print(' ');
16728 pw.print(r.trimMemoryLevel);
16730 pw.print(r.toShortString());
16732 pw.print(r.adjType);
16734 if (r.adjSource != null || r.adjTarget != null) {
16737 if (r.adjTarget instanceof ComponentName) {
16738 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16739 } else if (r.adjTarget != null) {
16740 pw.print(r.adjTarget.toString());
16742 pw.print("{null}");
16745 if (r.adjSource instanceof ProcessRecord) {
16747 pw.print(((ProcessRecord)r.adjSource).toShortString());
16749 } else if (r.adjSource != null) {
16750 pw.println(r.adjSource.toString());
16752 pw.println("{null}");
16758 pw.print("oom: max="); pw.print(r.maxAdj);
16759 pw.print(" curRaw="); pw.print(r.curRawAdj);
16760 pw.print(" setRaw="); pw.print(r.setRawAdj);
16761 pw.print(" cur="); pw.print(r.curAdj);
16762 pw.print(" set="); pw.println(r.setAdj);
16765 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16766 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16767 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16768 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16769 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16773 pw.print("cached="); pw.print(r.cached);
16774 pw.print(" empty="); pw.print(r.empty);
16775 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16777 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16778 if (r.lastCpuTime != 0) {
16779 long timeUsed = r.curCpuTime - r.lastCpuTime;
16782 pw.print("run cpu over ");
16783 TimeUtils.formatDuration(uptimeSince, pw);
16784 pw.print(" used ");
16785 TimeUtils.formatDuration(timeUsed, pw);
16787 pw.print((timeUsed*100)/uptimeSince);
16796 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16798 ArrayList<ProcessRecord> procs;
16799 synchronized (this) {
16800 if (args != null && args.length > start
16801 && args[start].charAt(0) != '-') {
16802 procs = new ArrayList<ProcessRecord>();
16805 pid = Integer.parseInt(args[start]);
16806 } catch (NumberFormatException e) {
16808 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16809 ProcessRecord proc = mLruProcesses.get(i);
16810 if (proc.pid == pid) {
16812 } else if (allPkgs && proc.pkgList != null
16813 && proc.pkgList.containsKey(args[start])) {
16815 } else if (proc.processName.equals(args[start])) {
16819 if (procs.size() <= 0) {
16823 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16829 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16830 PrintWriter pw, String[] args) {
16831 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16832 if (procs == null) {
16833 pw.println("No process found for: " + args[0]);
16837 long uptime = SystemClock.uptimeMillis();
16838 long realtime = SystemClock.elapsedRealtime();
16839 pw.println("Applications Graphics Acceleration Info:");
16840 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16842 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16843 ProcessRecord r = procs.get(i);
16844 if (r.thread != null) {
16845 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16848 TransferPipe tp = new TransferPipe();
16850 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16855 } catch (IOException e) {
16856 pw.println("Failure while dumping the app: " + r);
16858 } catch (RemoteException e) {
16859 pw.println("Got a RemoteException while dumping the app " + r);
16866 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16867 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16868 if (procs == null) {
16869 pw.println("No process found for: " + args[0]);
16873 pw.println("Applications Database Info:");
16875 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16876 ProcessRecord r = procs.get(i);
16877 if (r.thread != null) {
16878 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16881 TransferPipe tp = new TransferPipe();
16883 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16888 } catch (IOException e) {
16889 pw.println("Failure while dumping the app: " + r);
16891 } catch (RemoteException e) {
16892 pw.println("Got a RemoteException while dumping the app " + r);
16899 final static class MemItem {
16900 final boolean isProc;
16901 final String label;
16902 final String shortLabel;
16904 final long swapPss;
16906 final boolean hasActivities;
16907 ArrayList<MemItem> subitems;
16909 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16910 boolean _hasActivities) {
16913 shortLabel = _shortLabel;
16915 swapPss = _swapPss;
16917 hasActivities = _hasActivities;
16920 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16923 shortLabel = _shortLabel;
16925 swapPss = _swapPss;
16927 hasActivities = false;
16931 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16932 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16933 if (sort && !isCompact) {
16934 Collections.sort(items, new Comparator<MemItem>() {
16936 public int compare(MemItem lhs, MemItem rhs) {
16937 if (lhs.pss < rhs.pss) {
16939 } else if (lhs.pss > rhs.pss) {
16947 for (int i=0; i<items.size(); i++) {
16948 MemItem mi = items.get(i);
16951 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16952 mi.label, stringifyKBSize(mi.swapPss));
16954 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16956 } else if (mi.isProc) {
16957 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16958 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16959 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16960 pw.println(mi.hasActivities ? ",a" : ",e");
16962 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16963 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16965 if (mi.subitems != null) {
16966 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16967 true, isCompact, dumpSwapPss);
16972 // These are in KB.
16973 static final long[] DUMP_MEM_BUCKETS = new long[] {
16974 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16975 120*1024, 160*1024, 200*1024,
16976 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16977 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16980 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16981 boolean stackLike) {
16982 int start = label.lastIndexOf('.');
16983 if (start >= 0) start++;
16985 int end = label.length();
16986 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16987 if (DUMP_MEM_BUCKETS[i] >= memKB) {
16988 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16989 out.append(bucket);
16990 out.append(stackLike ? "MB." : "MB ");
16991 out.append(label, start, end);
16995 out.append(memKB/1024);
16996 out.append(stackLike ? "MB." : "MB ");
16997 out.append(label, start, end);
17000 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17001 ProcessList.NATIVE_ADJ,
17002 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17003 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17004 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17005 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17006 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17007 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17009 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17011 "System", "Persistent", "Persistent Service", "Foreground",
17012 "Visible", "Perceptible",
17013 "Heavy Weight", "Backup",
17014 "A Services", "Home",
17015 "Previous", "B Services", "Cached"
17017 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17019 "sys", "pers", "persvc", "fore",
17022 "servicea", "home",
17023 "prev", "serviceb", "cached"
17026 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17027 long realtime, boolean isCheckinRequest, boolean isCompact) {
17029 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17031 if (isCheckinRequest || isCompact) {
17032 // short checkin version
17033 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17035 pw.println("Applications Memory Usage (in Kilobytes):");
17036 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17040 private static final int KSM_SHARED = 0;
17041 private static final int KSM_SHARING = 1;
17042 private static final int KSM_UNSHARED = 2;
17043 private static final int KSM_VOLATILE = 3;
17045 private final long[] getKsmInfo() {
17046 long[] longOut = new long[4];
17047 final int[] SINGLE_LONG_FORMAT = new int[] {
17048 PROC_SPACE_TERM| PROC_OUT_LONG
17050 long[] longTmp = new long[1];
17051 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17052 SINGLE_LONG_FORMAT, null, longTmp, null);
17053 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17055 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17056 SINGLE_LONG_FORMAT, null, longTmp, null);
17057 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17059 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17060 SINGLE_LONG_FORMAT, null, longTmp, null);
17061 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17063 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17064 SINGLE_LONG_FORMAT, null, longTmp, null);
17065 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17069 private static String stringifySize(long size, int order) {
17070 Locale locale = Locale.US;
17073 return String.format(locale, "%,13d", size);
17075 return String.format(locale, "%,9dK", size / 1024);
17077 return String.format(locale, "%,5dM", size / 1024 / 1024);
17078 case 1024 * 1024 * 1024:
17079 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17081 throw new IllegalArgumentException("Invalid size order");
17085 private static String stringifyKBSize(long size) {
17086 return stringifySize(size * 1024, 1024);
17089 // Update this version number in case you change the 'compact' format
17090 private static final int MEMINFO_COMPACT_VERSION = 1;
17092 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17093 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17094 boolean dumpDetails = false;
17095 boolean dumpFullDetails = false;
17096 boolean dumpDalvik = false;
17097 boolean dumpSummaryOnly = false;
17098 boolean dumpUnreachable = false;
17099 boolean oomOnly = false;
17100 boolean isCompact = false;
17101 boolean localOnly = false;
17102 boolean packages = false;
17103 boolean isCheckinRequest = false;
17104 boolean dumpSwapPss = false;
17107 while (opti < args.length) {
17108 String opt = args[opti];
17109 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17113 if ("-a".equals(opt)) {
17114 dumpDetails = true;
17115 dumpFullDetails = true;
17117 dumpSwapPss = true;
17118 } else if ("-d".equals(opt)) {
17120 } else if ("-c".equals(opt)) {
17122 } else if ("-s".equals(opt)) {
17123 dumpDetails = true;
17124 dumpSummaryOnly = true;
17125 } else if ("-S".equals(opt)) {
17126 dumpSwapPss = true;
17127 } else if ("--unreachable".equals(opt)) {
17128 dumpUnreachable = true;
17129 } else if ("--oom".equals(opt)) {
17131 } else if ("--local".equals(opt)) {
17133 } else if ("--package".equals(opt)) {
17135 } else if ("--checkin".equals(opt)) {
17136 isCheckinRequest = true;
17138 } else if ("-h".equals(opt)) {
17139 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17140 pw.println(" -a: include all available information for each process.");
17141 pw.println(" -d: include dalvik details.");
17142 pw.println(" -c: dump in a compact machine-parseable representation.");
17143 pw.println(" -s: dump only summary of application memory usage.");
17144 pw.println(" -S: dump also SwapPss.");
17145 pw.println(" --oom: only show processes organized by oom adj.");
17146 pw.println(" --local: only collect details locally, don't call process.");
17147 pw.println(" --package: interpret process arg as package, dumping all");
17148 pw.println(" processes that have loaded that package.");
17149 pw.println(" --checkin: dump data for a checkin");
17150 pw.println("If [process] is specified it can be the name or ");
17151 pw.println("pid of a specific process to dump.");
17154 pw.println("Unknown argument: " + opt + "; use -h for help");
17158 long uptime = SystemClock.uptimeMillis();
17159 long realtime = SystemClock.elapsedRealtime();
17160 final long[] tmpLong = new long[1];
17162 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17163 if (procs == null) {
17164 // No Java processes. Maybe they want to print a native process.
17165 if (args != null && args.length > opti
17166 && args[opti].charAt(0) != '-') {
17167 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17168 = new ArrayList<ProcessCpuTracker.Stats>();
17169 updateCpuStatsNow();
17172 findPid = Integer.parseInt(args[opti]);
17173 } catch (NumberFormatException e) {
17175 synchronized (mProcessCpuTracker) {
17176 final int N = mProcessCpuTracker.countStats();
17177 for (int i=0; i<N; i++) {
17178 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17179 if (st.pid == findPid || (st.baseName != null
17180 && st.baseName.equals(args[opti]))) {
17181 nativeProcs.add(st);
17185 if (nativeProcs.size() > 0) {
17186 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17188 Debug.MemoryInfo mi = null;
17189 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17190 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17191 final int pid = r.pid;
17192 if (!isCheckinRequest && dumpDetails) {
17193 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17196 mi = new Debug.MemoryInfo();
17198 if (dumpDetails || (!brief && !oomOnly)) {
17199 Debug.getMemoryInfo(pid, mi);
17201 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17202 mi.dalvikPrivateDirty = (int)tmpLong[0];
17204 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17205 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17206 if (isCheckinRequest) {
17213 pw.println("No process found for: " + args[opti]);
17217 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17218 dumpDetails = true;
17221 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17223 String[] innerArgs = new String[args.length-opti];
17224 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17226 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17227 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17228 long nativePss = 0;
17229 long nativeSwapPss = 0;
17230 long dalvikPss = 0;
17231 long dalvikSwapPss = 0;
17232 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17234 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17237 long otherSwapPss = 0;
17238 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17239 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17241 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17242 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17243 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17244 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17247 long totalSwapPss = 0;
17248 long cachedPss = 0;
17249 long cachedSwapPss = 0;
17250 boolean hasSwapPss = false;
17252 Debug.MemoryInfo mi = null;
17253 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17254 final ProcessRecord r = procs.get(i);
17255 final IApplicationThread thread;
17258 final boolean hasActivities;
17259 synchronized (this) {
17262 oomAdj = r.getSetAdjWithServices();
17263 hasActivities = r.activities.size() > 0;
17265 if (thread != null) {
17266 if (!isCheckinRequest && dumpDetails) {
17267 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17270 mi = new Debug.MemoryInfo();
17272 if (dumpDetails || (!brief && !oomOnly)) {
17273 Debug.getMemoryInfo(pid, mi);
17274 hasSwapPss = mi.hasSwappedOutPss;
17276 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17277 mi.dalvikPrivateDirty = (int)tmpLong[0];
17281 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17282 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17283 if (isCheckinRequest) {
17289 TransferPipe tp = new TransferPipe();
17291 thread.dumpMemInfo(tp.getWriteFd(),
17292 mi, isCheckinRequest, dumpFullDetails,
17293 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17298 } catch (IOException e) {
17299 if (!isCheckinRequest) {
17300 pw.println("Got IoException! " + e);
17303 } catch (RemoteException e) {
17304 if (!isCheckinRequest) {
17305 pw.println("Got RemoteException! " + e);
17312 final long myTotalPss = mi.getTotalPss();
17313 final long myTotalUss = mi.getTotalUss();
17314 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17316 synchronized (this) {
17317 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17318 // Record this for posterity if the process has been stable.
17319 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17323 if (!isCheckinRequest && mi != null) {
17324 totalPss += myTotalPss;
17325 totalSwapPss += myTotalSwapPss;
17326 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17327 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17328 myTotalSwapPss, pid, hasActivities);
17329 procMems.add(pssItem);
17330 procMemsMap.put(pid, pssItem);
17332 nativePss += mi.nativePss;
17333 nativeSwapPss += mi.nativeSwappedOutPss;
17334 dalvikPss += mi.dalvikPss;
17335 dalvikSwapPss += mi.dalvikSwappedOutPss;
17336 for (int j=0; j<dalvikSubitemPss.length; j++) {
17337 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17338 dalvikSubitemSwapPss[j] +=
17339 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17341 otherPss += mi.otherPss;
17342 otherSwapPss += mi.otherSwappedOutPss;
17343 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17344 long mem = mi.getOtherPss(j);
17347 mem = mi.getOtherSwappedOutPss(j);
17348 miscSwapPss[j] += mem;
17349 otherSwapPss -= mem;
17352 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17353 cachedPss += myTotalPss;
17354 cachedSwapPss += myTotalSwapPss;
17357 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17358 if (oomIndex == (oomPss.length - 1)
17359 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17360 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17361 oomPss[oomIndex] += myTotalPss;
17362 oomSwapPss[oomIndex] += myTotalSwapPss;
17363 if (oomProcs[oomIndex] == null) {
17364 oomProcs[oomIndex] = new ArrayList<MemItem>();
17366 oomProcs[oomIndex].add(pssItem);
17374 long nativeProcTotalPss = 0;
17376 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17377 // If we are showing aggregations, also look for native processes to
17378 // include so that our aggregations are more accurate.
17379 updateCpuStatsNow();
17381 synchronized (mProcessCpuTracker) {
17382 final int N = mProcessCpuTracker.countStats();
17383 for (int i=0; i<N; i++) {
17384 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17385 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17387 mi = new Debug.MemoryInfo();
17389 if (!brief && !oomOnly) {
17390 Debug.getMemoryInfo(st.pid, mi);
17392 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17393 mi.nativePrivateDirty = (int)tmpLong[0];
17396 final long myTotalPss = mi.getTotalPss();
17397 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17398 totalPss += myTotalPss;
17399 nativeProcTotalPss += myTotalPss;
17401 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17402 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17403 procMems.add(pssItem);
17405 nativePss += mi.nativePss;
17406 nativeSwapPss += mi.nativeSwappedOutPss;
17407 dalvikPss += mi.dalvikPss;
17408 dalvikSwapPss += mi.dalvikSwappedOutPss;
17409 for (int j=0; j<dalvikSubitemPss.length; j++) {
17410 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17411 dalvikSubitemSwapPss[j] +=
17412 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17414 otherPss += mi.otherPss;
17415 otherSwapPss += mi.otherSwappedOutPss;
17416 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17417 long mem = mi.getOtherPss(j);
17420 mem = mi.getOtherSwappedOutPss(j);
17421 miscSwapPss[j] += mem;
17422 otherSwapPss -= mem;
17424 oomPss[0] += myTotalPss;
17425 oomSwapPss[0] += myTotalSwapPss;
17426 if (oomProcs[0] == null) {
17427 oomProcs[0] = new ArrayList<MemItem>();
17429 oomProcs[0].add(pssItem);
17434 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17436 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17437 final int dalvikId = -2;
17438 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17439 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17440 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17441 String label = Debug.MemoryInfo.getOtherLabel(j);
17442 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17444 if (dalvikSubitemPss.length > 0) {
17445 // Add dalvik subitems.
17446 for (MemItem memItem : catMems) {
17447 int memItemStart = 0, memItemEnd = 0;
17448 if (memItem.id == dalvikId) {
17449 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17450 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17451 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17452 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17453 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17454 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17455 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17456 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17457 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17458 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17459 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17461 continue; // No subitems, continue.
17463 memItem.subitems = new ArrayList<MemItem>();
17464 for (int j=memItemStart; j<=memItemEnd; j++) {
17465 final String name = Debug.MemoryInfo.getOtherLabel(
17466 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17467 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17468 dalvikSubitemSwapPss[j], j));
17473 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17474 for (int j=0; j<oomPss.length; j++) {
17475 if (oomPss[j] != 0) {
17476 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17477 : DUMP_MEM_OOM_LABEL[j];
17478 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17479 DUMP_MEM_OOM_ADJ[j]);
17480 item.subitems = oomProcs[j];
17485 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17486 if (!brief && !oomOnly && !isCompact) {
17488 pw.println("Total PSS by process:");
17489 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17493 pw.println("Total PSS by OOM adjustment:");
17495 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17496 if (!brief && !oomOnly) {
17497 PrintWriter out = categoryPw != null ? categoryPw : pw;
17500 out.println("Total PSS by category:");
17502 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17507 MemInfoReader memInfo = new MemInfoReader();
17508 memInfo.readMemInfo();
17509 if (nativeProcTotalPss > 0) {
17510 synchronized (this) {
17511 final long cachedKb = memInfo.getCachedSizeKb();
17512 final long freeKb = memInfo.getFreeSizeKb();
17513 final long zramKb = memInfo.getZramTotalSizeKb();
17514 final long kernelKb = memInfo.getKernelUsedSizeKb();
17515 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17516 kernelKb*1024, nativeProcTotalPss*1024);
17517 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17518 nativeProcTotalPss);
17523 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17524 pw.print(" (status ");
17525 switch (mLastMemoryLevel) {
17526 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17527 pw.println("normal)");
17529 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17530 pw.println("moderate)");
17532 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17533 pw.println("low)");
17535 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17536 pw.println("critical)");
17539 pw.print(mLastMemoryLevel);
17543 pw.print(" Free RAM: ");
17544 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17545 + memInfo.getFreeSizeKb()));
17547 pw.print(stringifyKBSize(cachedPss));
17548 pw.print(" cached pss + ");
17549 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17550 pw.print(" cached kernel + ");
17551 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17552 pw.println(" free)");
17554 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17555 pw.print(cachedPss + memInfo.getCachedSizeKb()
17556 + memInfo.getFreeSizeKb()); pw.print(",");
17557 pw.println(totalPss - cachedPss);
17560 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17561 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17562 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17564 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17565 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17566 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17567 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17568 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17570 pw.print("lostram,"); pw.println(lostRAM);
17573 if (memInfo.getZramTotalSizeKb() != 0) {
17575 pw.print(" ZRAM: ");
17576 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17577 pw.print(" physical used for ");
17578 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17579 - memInfo.getSwapFreeSizeKb()));
17580 pw.print(" in swap (");
17581 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17582 pw.println(" total swap)");
17584 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17585 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17586 pw.println(memInfo.getSwapFreeSizeKb());
17589 final long[] ksm = getKsmInfo();
17591 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17592 || ksm[KSM_VOLATILE] != 0) {
17593 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17594 pw.print(" saved from shared ");
17595 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17596 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17597 pw.print(" unshared; ");
17598 pw.print(stringifyKBSize(
17599 ksm[KSM_VOLATILE])); pw.println(" volatile");
17601 pw.print(" Tuning: ");
17602 pw.print(ActivityManager.staticGetMemoryClass());
17603 pw.print(" (large ");
17604 pw.print(ActivityManager.staticGetLargeMemoryClass());
17605 pw.print("), oom ");
17606 pw.print(stringifySize(
17607 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17608 pw.print(", restore limit ");
17609 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17610 if (ActivityManager.isLowRamDeviceStatic()) {
17611 pw.print(" (low-ram)");
17613 if (ActivityManager.isHighEndGfx()) {
17614 pw.print(" (high-end-gfx)");
17618 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17619 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17620 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17621 pw.print("tuning,");
17622 pw.print(ActivityManager.staticGetMemoryClass());
17624 pw.print(ActivityManager.staticGetLargeMemoryClass());
17626 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17627 if (ActivityManager.isLowRamDeviceStatic()) {
17628 pw.print(",low-ram");
17630 if (ActivityManager.isHighEndGfx()) {
17631 pw.print(",high-end-gfx");
17639 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17640 long memtrack, String name) {
17642 sb.append(ProcessList.makeOomAdjString(oomAdj));
17644 sb.append(ProcessList.makeProcStateString(procState));
17646 ProcessList.appendRamKb(sb, pss);
17649 if (memtrack > 0) {
17651 sb.append(stringifyKBSize(memtrack));
17652 sb.append(" memtrack)");
17656 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17657 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17658 sb.append(" (pid ");
17661 sb.append(mi.adjType);
17663 if (mi.adjReason != null) {
17665 sb.append(mi.adjReason);
17670 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17671 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17672 for (int i=0, N=memInfos.size(); i<N; i++) {
17673 ProcessMemInfo mi = memInfos.get(i);
17674 infoMap.put(mi.pid, mi);
17676 updateCpuStatsNow();
17677 long[] memtrackTmp = new long[1];
17678 final List<ProcessCpuTracker.Stats> stats;
17679 // Get a list of Stats that have vsize > 0
17680 synchronized (mProcessCpuTracker) {
17681 stats = mProcessCpuTracker.getStats((st) -> {
17682 return st.vsize > 0;
17685 final int statsCount = stats.size();
17686 for (int i = 0; i < statsCount; i++) {
17687 ProcessCpuTracker.Stats st = stats.get(i);
17688 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17690 if (infoMap.indexOfKey(st.pid) < 0) {
17691 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17692 ProcessList.NATIVE_ADJ, -1, "native", null);
17694 mi.memtrack = memtrackTmp[0];
17701 long totalMemtrack = 0;
17702 for (int i=0, N=memInfos.size(); i<N; i++) {
17703 ProcessMemInfo mi = memInfos.get(i);
17705 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17706 mi.memtrack = memtrackTmp[0];
17708 totalPss += mi.pss;
17709 totalMemtrack += mi.memtrack;
17711 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17712 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17713 if (lhs.oomAdj != rhs.oomAdj) {
17714 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17716 if (lhs.pss != rhs.pss) {
17717 return lhs.pss < rhs.pss ? 1 : -1;
17723 StringBuilder tag = new StringBuilder(128);
17724 StringBuilder stack = new StringBuilder(128);
17725 tag.append("Low on memory -- ");
17726 appendMemBucket(tag, totalPss, "total", false);
17727 appendMemBucket(stack, totalPss, "total", true);
17729 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17730 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17731 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17733 boolean firstLine = true;
17734 int lastOomAdj = Integer.MIN_VALUE;
17735 long extraNativeRam = 0;
17736 long extraNativeMemtrack = 0;
17737 long cachedPss = 0;
17738 for (int i=0, N=memInfos.size(); i<N; i++) {
17739 ProcessMemInfo mi = memInfos.get(i);
17741 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17742 cachedPss += mi.pss;
17745 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17746 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17747 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17748 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17749 if (lastOomAdj != mi.oomAdj) {
17750 lastOomAdj = mi.oomAdj;
17751 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17754 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17759 stack.append("\n\t at ");
17767 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17768 appendMemBucket(tag, mi.pss, mi.name, false);
17770 appendMemBucket(stack, mi.pss, mi.name, true);
17771 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17772 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17774 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17775 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17776 stack.append(DUMP_MEM_OOM_LABEL[k]);
17778 stack.append(DUMP_MEM_OOM_ADJ[k]);
17785 appendMemInfo(fullNativeBuilder, mi);
17786 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17787 // The short form only has native processes that are >= 512K.
17788 if (mi.pss >= 512) {
17789 appendMemInfo(shortNativeBuilder, mi);
17791 extraNativeRam += mi.pss;
17792 extraNativeMemtrack += mi.memtrack;
17795 // Short form has all other details, but if we have collected RAM
17796 // from smaller native processes let's dump a summary of that.
17797 if (extraNativeRam > 0) {
17798 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17799 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17800 shortNativeBuilder.append('\n');
17801 extraNativeRam = 0;
17803 appendMemInfo(fullJavaBuilder, mi);
17807 fullJavaBuilder.append(" ");
17808 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17809 fullJavaBuilder.append(": TOTAL");
17810 if (totalMemtrack > 0) {
17811 fullJavaBuilder.append(" (");
17812 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17813 fullJavaBuilder.append(" memtrack)");
17816 fullJavaBuilder.append("\n");
17818 MemInfoReader memInfo = new MemInfoReader();
17819 memInfo.readMemInfo();
17820 final long[] infos = memInfo.getRawInfo();
17822 StringBuilder memInfoBuilder = new StringBuilder(1024);
17823 Debug.getMemInfo(infos);
17824 memInfoBuilder.append(" MemInfo: ");
17825 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17826 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17827 memInfoBuilder.append(stringifyKBSize(
17828 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17829 memInfoBuilder.append(stringifyKBSize(
17830 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17831 memInfoBuilder.append(stringifyKBSize(
17832 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17833 memInfoBuilder.append(" ");
17834 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17835 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17836 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17837 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17838 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17839 memInfoBuilder.append(" ZRAM: ");
17840 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17841 memInfoBuilder.append(" RAM, ");
17842 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17843 memInfoBuilder.append(" swap total, ");
17844 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17845 memInfoBuilder.append(" swap free\n");
17847 final long[] ksm = getKsmInfo();
17848 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17849 || ksm[KSM_VOLATILE] != 0) {
17850 memInfoBuilder.append(" KSM: ");
17851 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17852 memInfoBuilder.append(" saved from shared ");
17853 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17854 memInfoBuilder.append("\n ");
17855 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17856 memInfoBuilder.append(" unshared; ");
17857 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17858 memInfoBuilder.append(" volatile\n");
17860 memInfoBuilder.append(" Free RAM: ");
17861 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17862 + memInfo.getFreeSizeKb()));
17863 memInfoBuilder.append("\n");
17864 memInfoBuilder.append(" Used RAM: ");
17865 memInfoBuilder.append(stringifyKBSize(
17866 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17867 memInfoBuilder.append("\n");
17868 memInfoBuilder.append(" Lost RAM: ");
17869 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17870 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17871 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17872 memInfoBuilder.append("\n");
17873 Slog.i(TAG, "Low on memory:");
17874 Slog.i(TAG, shortNativeBuilder.toString());
17875 Slog.i(TAG, fullJavaBuilder.toString());
17876 Slog.i(TAG, memInfoBuilder.toString());
17878 StringBuilder dropBuilder = new StringBuilder(1024);
17880 StringWriter oomSw = new StringWriter();
17881 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17882 StringWriter catSw = new StringWriter();
17883 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17884 String[] emptyArgs = new String[] { };
17885 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17887 String oomString = oomSw.toString();
17889 dropBuilder.append("Low on memory:");
17890 dropBuilder.append(stack);
17891 dropBuilder.append('\n');
17892 dropBuilder.append(fullNativeBuilder);
17893 dropBuilder.append(fullJavaBuilder);
17894 dropBuilder.append('\n');
17895 dropBuilder.append(memInfoBuilder);
17896 dropBuilder.append('\n');
17898 dropBuilder.append(oomString);
17899 dropBuilder.append('\n');
17901 StringWriter catSw = new StringWriter();
17902 synchronized (ActivityManagerService.this) {
17903 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17904 String[] emptyArgs = new String[] { };
17906 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17908 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17909 false, null).dumpLocked();
17911 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17914 dropBuilder.append(catSw.toString());
17915 addErrorToDropBox("lowmem", null, "system_server", null,
17916 null, tag.toString(), dropBuilder.toString(), null, null);
17917 //Slog.i(TAG, "Sent to dropbox:");
17918 //Slog.i(TAG, dropBuilder.toString());
17919 synchronized (ActivityManagerService.this) {
17920 long now = SystemClock.uptimeMillis();
17921 if (mLastMemUsageReportTime < now) {
17922 mLastMemUsageReportTime = now;
17928 * Searches array of arguments for the specified string
17929 * @param args array of argument strings
17930 * @param value value to search for
17931 * @return true if the value is contained in the array
17933 private static boolean scanArgs(String[] args, String value) {
17934 if (args != null) {
17935 for (String arg : args) {
17936 if (value.equals(arg)) {
17944 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17945 ContentProviderRecord cpr, boolean always) {
17946 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17948 if (!inLaunching || always) {
17949 synchronized (cpr) {
17950 cpr.launchingApp = null;
17953 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17954 String names[] = cpr.info.authority.split(";");
17955 for (int j = 0; j < names.length; j++) {
17956 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17960 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17961 ContentProviderConnection conn = cpr.connections.get(i);
17962 if (conn.waiting) {
17963 // If this connection is waiting for the provider, then we don't
17964 // need to mess with its process unless we are always removing
17965 // or for some reason the provider is not currently launching.
17966 if (inLaunching && !always) {
17970 ProcessRecord capp = conn.client;
17972 if (conn.stableCount > 0) {
17973 if (!capp.persistent && capp.thread != null
17975 && capp.pid != MY_PID) {
17976 capp.kill("depends on provider "
17977 + cpr.name.flattenToShortString()
17978 + " in dying proc " + (proc != null ? proc.processName : "??")
17979 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17981 } else if (capp.thread != null && conn.provider.provider != null) {
17983 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17984 } catch (RemoteException e) {
17986 // In the protocol here, we don't expect the client to correctly
17987 // clean up this connection, we'll just remove it.
17988 cpr.connections.remove(i);
17989 if (conn.client.conProviders.remove(conn)) {
17990 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17995 if (inLaunching && always) {
17996 mLaunchingProviders.remove(cpr);
17998 return inLaunching;
18002 * Main code for cleaning up a process when it has gone away. This is
18003 * called both as a result of the process dying, or directly when stopping
18004 * a process when running in single process mode.
18006 * @return Returns true if the given process has been restarted, so the
18007 * app that was passed in must remain on the process lists.
18009 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18010 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18012 removeLruProcessLocked(app);
18013 ProcessList.remove(app.pid);
18016 mProcessesToGc.remove(app);
18017 mPendingPssProcesses.remove(app);
18019 // Dismiss any open dialogs.
18020 if (app.crashDialog != null && !app.forceCrashReport) {
18021 app.crashDialog.dismiss();
18022 app.crashDialog = null;
18024 if (app.anrDialog != null) {
18025 app.anrDialog.dismiss();
18026 app.anrDialog = null;
18028 if (app.waitDialog != null) {
18029 app.waitDialog.dismiss();
18030 app.waitDialog = null;
18033 app.crashing = false;
18034 app.notResponding = false;
18036 app.resetPackageList(mProcessStats);
18037 app.unlinkDeathRecipient();
18038 app.makeInactive(mProcessStats);
18039 app.waitingToKill = null;
18040 app.forcingToImportant = null;
18041 updateProcessForegroundLocked(app, false, false);
18042 app.foregroundActivities = false;
18043 app.hasShownUi = false;
18044 app.treatLikeActivity = false;
18045 app.hasAboveClient = false;
18046 app.hasClientActivities = false;
18048 mServices.killServicesLocked(app, allowRestart);
18050 boolean restart = false;
18052 // Remove published content providers.
18053 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18054 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18055 final boolean always = app.bad || !allowRestart;
18056 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18057 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18058 // We left the provider in the launching list, need to
18063 cpr.provider = null;
18066 app.pubProviders.clear();
18068 // Take care of any launching providers waiting for this process.
18069 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18073 // Unregister from connected content providers.
18074 if (!app.conProviders.isEmpty()) {
18075 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18076 ContentProviderConnection conn = app.conProviders.get(i);
18077 conn.provider.connections.remove(conn);
18078 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18079 conn.provider.name);
18081 app.conProviders.clear();
18084 // At this point there may be remaining entries in mLaunchingProviders
18085 // where we were the only one waiting, so they are no longer of use.
18086 // Look for these and clean up if found.
18087 // XXX Commented out for now. Trying to figure out a way to reproduce
18088 // the actual situation to identify what is actually going on.
18090 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18091 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18092 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18093 synchronized (cpr) {
18094 cpr.launchingApp = null;
18101 skipCurrentReceiverLocked(app);
18103 // Unregister any receivers.
18104 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18105 removeReceiverLocked(app.receivers.valueAt(i));
18107 app.receivers.clear();
18109 // If the app is undergoing backup, tell the backup manager about it
18110 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18111 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18112 + mBackupTarget.appInfo + " died during backup");
18113 mHandler.post(new Runnable() {
18117 IBackupManager bm = IBackupManager.Stub.asInterface(
18118 ServiceManager.getService(Context.BACKUP_SERVICE));
18119 bm.agentDisconnected(app.info.packageName);
18120 } catch (RemoteException e) {
18121 // can't happen; backup manager is local
18127 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18128 ProcessChangeItem item = mPendingProcessChanges.get(i);
18129 if (item.pid == app.pid) {
18130 mPendingProcessChanges.remove(i);
18131 mAvailProcessChanges.add(item);
18134 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18135 null).sendToTarget();
18137 // If the caller is restarting this app, then leave it in its
18138 // current lists and let the caller take care of it.
18143 if (!app.persistent || app.isolated) {
18144 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18145 "Removing non-persistent process during cleanup: " + app);
18146 if (!replacingPid) {
18147 removeProcessNameLocked(app.processName, app.uid, app);
18149 if (mHeavyWeightProcess == app) {
18150 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18151 mHeavyWeightProcess.userId, 0));
18152 mHeavyWeightProcess = null;
18154 } else if (!app.removed) {
18155 // This app is persistent, so we need to keep its record around.
18156 // If it is not already on the pending app list, add it there
18157 // and start a new process for it.
18158 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18159 mPersistentStartingProcesses.add(app);
18163 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18164 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18165 mProcessesOnHold.remove(app);
18167 if (app == mHomeProcess) {
18168 mHomeProcess = null;
18170 if (app == mPreviousProcess) {
18171 mPreviousProcess = null;
18174 if (restart && !app.isolated) {
18175 // We have components that still need to be running in the
18176 // process, so re-launch it.
18178 ProcessList.remove(app.pid);
18180 addProcessNameLocked(app);
18181 startProcessLocked(app, "restart", app.processName);
18183 } else if (app.pid > 0 && app.pid != MY_PID) {
18186 synchronized (mPidsSelfLocked) {
18187 mPidsSelfLocked.remove(app.pid);
18188 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18190 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18191 if (app.isolated) {
18192 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18199 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18200 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18201 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18202 if (cpr.launchingApp == app) {
18209 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18210 // Look through the content providers we are waiting to have launched,
18211 // and if any run in this process then either schedule a restart of
18212 // the process or kill the client waiting for it if this process has
18214 boolean restart = false;
18215 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18216 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18217 if (cpr.launchingApp == app) {
18218 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18221 removeDyingProviderLocked(app, cpr, true);
18228 // =========================================================
18230 // =========================================================
18233 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18235 enforceNotIsolatedCaller("getServices");
18237 final int callingUid = Binder.getCallingUid();
18238 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18239 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18240 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18242 synchronized (this) {
18243 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18244 allowed, canInteractAcrossUsers);
18249 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18250 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18251 synchronized (this) {
18252 return mServices.getRunningServiceControlPanelLocked(name);
18257 public ComponentName startService(IApplicationThread caller, Intent service,
18258 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18259 throws TransactionTooLargeException {
18260 enforceNotIsolatedCaller("startService");
18261 // Refuse possible leaked file descriptors
18262 if (service != null && service.hasFileDescriptors() == true) {
18263 throw new IllegalArgumentException("File descriptors passed in Intent");
18266 if (callingPackage == null) {
18267 throw new IllegalArgumentException("callingPackage cannot be null");
18270 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18271 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18272 synchronized(this) {
18273 final int callingPid = Binder.getCallingPid();
18274 final int callingUid = Binder.getCallingUid();
18275 final long origId = Binder.clearCallingIdentity();
18278 res = mServices.startServiceLocked(caller, service,
18279 resolvedType, callingPid, callingUid,
18280 requireForeground, callingPackage, userId);
18282 Binder.restoreCallingIdentity(origId);
18288 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18289 boolean fgRequired, String callingPackage, int userId)
18290 throws TransactionTooLargeException {
18291 synchronized(this) {
18292 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18293 "startServiceInPackage: " + service + " type=" + resolvedType);
18294 final long origId = Binder.clearCallingIdentity();
18297 res = mServices.startServiceLocked(null, service,
18298 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18300 Binder.restoreCallingIdentity(origId);
18307 public int stopService(IApplicationThread caller, Intent service,
18308 String resolvedType, int userId) {
18309 enforceNotIsolatedCaller("stopService");
18310 // Refuse possible leaked file descriptors
18311 if (service != null && service.hasFileDescriptors() == true) {
18312 throw new IllegalArgumentException("File descriptors passed in Intent");
18315 synchronized(this) {
18316 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18321 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18322 enforceNotIsolatedCaller("peekService");
18323 // Refuse possible leaked file descriptors
18324 if (service != null && service.hasFileDescriptors() == true) {
18325 throw new IllegalArgumentException("File descriptors passed in Intent");
18328 if (callingPackage == null) {
18329 throw new IllegalArgumentException("callingPackage cannot be null");
18332 synchronized(this) {
18333 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18338 public boolean stopServiceToken(ComponentName className, IBinder token,
18340 synchronized(this) {
18341 return mServices.stopServiceTokenLocked(className, token, startId);
18346 public void setServiceForeground(ComponentName className, IBinder token,
18347 int id, Notification notification, int flags) {
18348 synchronized(this) {
18349 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18354 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18355 boolean requireFull, String name, String callerPackage) {
18356 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18357 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18360 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18361 String className, int flags) {
18362 boolean result = false;
18363 // For apps that don't have pre-defined UIDs, check for permission
18364 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18365 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18366 if (ActivityManager.checkUidPermission(
18367 INTERACT_ACROSS_USERS,
18368 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18369 ComponentName comp = new ComponentName(aInfo.packageName, className);
18370 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18371 + " requests FLAG_SINGLE_USER, but app does not hold "
18372 + INTERACT_ACROSS_USERS;
18374 throw new SecurityException(msg);
18376 // Permission passed
18379 } else if ("system".equals(componentProcessName)) {
18381 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18382 // Phone app and persistent apps are allowed to export singleuser providers.
18383 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18384 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18386 if (DEBUG_MU) Slog.v(TAG_MU,
18387 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18388 + Integer.toHexString(flags) + ") = " + result);
18393 * Checks to see if the caller is in the same app as the singleton
18394 * component, or the component is in a special app. It allows special apps
18395 * to export singleton components but prevents exporting singleton
18396 * components for regular apps.
18398 boolean isValidSingletonCall(int callingUid, int componentUid) {
18399 int componentAppId = UserHandle.getAppId(componentUid);
18400 return UserHandle.isSameApp(callingUid, componentUid)
18401 || componentAppId == SYSTEM_UID
18402 || componentAppId == PHONE_UID
18403 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18404 == PackageManager.PERMISSION_GRANTED;
18407 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18408 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18409 int userId) throws TransactionTooLargeException {
18410 enforceNotIsolatedCaller("bindService");
18412 // Refuse possible leaked file descriptors
18413 if (service != null && service.hasFileDescriptors() == true) {
18414 throw new IllegalArgumentException("File descriptors passed in Intent");
18417 if (callingPackage == null) {
18418 throw new IllegalArgumentException("callingPackage cannot be null");
18421 synchronized(this) {
18422 return mServices.bindServiceLocked(caller, token, service,
18423 resolvedType, connection, flags, callingPackage, userId);
18427 public boolean unbindService(IServiceConnection connection) {
18428 synchronized (this) {
18429 return mServices.unbindServiceLocked(connection);
18433 public void publishService(IBinder token, Intent intent, IBinder service) {
18434 // Refuse possible leaked file descriptors
18435 if (intent != null && intent.hasFileDescriptors() == true) {
18436 throw new IllegalArgumentException("File descriptors passed in Intent");
18439 synchronized(this) {
18440 if (!(token instanceof ServiceRecord)) {
18441 throw new IllegalArgumentException("Invalid service token");
18443 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18447 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18448 // Refuse possible leaked file descriptors
18449 if (intent != null && intent.hasFileDescriptors() == true) {
18450 throw new IllegalArgumentException("File descriptors passed in Intent");
18453 synchronized(this) {
18454 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18458 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18459 synchronized(this) {
18460 if (!(token instanceof ServiceRecord)) {
18461 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18462 throw new IllegalArgumentException("Invalid service token");
18464 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18468 // =========================================================
18469 // BACKUP AND RESTORE
18470 // =========================================================
18472 // Cause the target app to be launched if necessary and its backup agent
18473 // instantiated. The backup agent will invoke backupAgentCreated() on the
18474 // activity manager to announce its creation.
18475 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18476 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18477 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18479 IPackageManager pm = AppGlobals.getPackageManager();
18480 ApplicationInfo app = null;
18482 app = pm.getApplicationInfo(packageName, 0, userId);
18483 } catch (RemoteException e) {
18484 // can't happen; package manager is process-local
18487 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18494 synchronized(this) {
18495 // !!! TODO: currently no check here that we're already bound
18496 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18497 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18498 synchronized (stats) {
18499 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18502 // Backup agent is now in use, its package can't be stopped.
18504 AppGlobals.getPackageManager().setPackageStoppedState(
18505 app.packageName, false, UserHandle.getUserId(app.uid));
18506 } catch (RemoteException e) {
18507 } catch (IllegalArgumentException e) {
18508 Slog.w(TAG, "Failed trying to unstop package "
18509 + app.packageName + ": " + e);
18512 BackupRecord r = new BackupRecord(ss, app, backupMode);
18513 ComponentName hostingName =
18514 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18515 ? new ComponentName(app.packageName, app.backupAgentName)
18516 : new ComponentName("android", "FullBackupAgent");
18517 // startProcessLocked() returns existing proc's record if it's already running
18518 ProcessRecord proc = startProcessLocked(app.processName, app,
18519 false, 0, "backup", hostingName, false, false, false);
18520 if (proc == null) {
18521 Slog.e(TAG, "Unable to start backup agent process " + r);
18525 // If the app is a regular app (uid >= 10000) and not the system server or phone
18526 // process, etc, then mark it as being in full backup so that certain calls to the
18527 // process can be blocked. This is not reset to false anywhere because we kill the
18528 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18529 if (UserHandle.isApp(app.uid) &&
18530 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18531 proc.inFullBackup = true;
18534 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18535 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18537 mBackupAppName = app.packageName;
18539 // Try not to kill the process during backup
18540 updateOomAdjLocked(proc, true);
18542 // If the process is already attached, schedule the creation of the backup agent now.
18543 // If it is not yet live, this will be done when it attaches to the framework.
18544 if (proc.thread != null) {
18545 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18547 proc.thread.scheduleCreateBackupAgent(app,
18548 compatibilityInfoForPackageLocked(app), backupMode);
18549 } catch (RemoteException e) {
18550 // Will time out on the backup manager side
18553 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18555 // Invariants: at this point, the target app process exists and the application
18556 // is either already running or in the process of coming up. mBackupTarget and
18557 // mBackupAppName describe the app, so that when it binds back to the AM we
18558 // know that it's scheduled for a backup-agent operation.
18561 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18562 if (oldBackupUid != -1) {
18563 js.removeBackingUpUid(oldBackupUid);
18565 if (newBackupUid != -1) {
18566 js.addBackingUpUid(newBackupUid);
18573 public void clearPendingBackup() {
18574 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18575 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18577 synchronized (this) {
18578 mBackupTarget = null;
18579 mBackupAppName = null;
18582 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18583 js.clearAllBackingUpUids();
18586 // A backup agent has just come up
18587 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18588 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18591 synchronized(this) {
18592 if (!agentPackageName.equals(mBackupAppName)) {
18593 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18598 long oldIdent = Binder.clearCallingIdentity();
18600 IBackupManager bm = IBackupManager.Stub.asInterface(
18601 ServiceManager.getService(Context.BACKUP_SERVICE));
18602 bm.agentConnected(agentPackageName, agent);
18603 } catch (RemoteException e) {
18604 // can't happen; the backup manager service is local
18605 } catch (Exception e) {
18606 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18607 e.printStackTrace();
18609 Binder.restoreCallingIdentity(oldIdent);
18613 // done with this agent
18614 public void unbindBackupAgent(ApplicationInfo appInfo) {
18615 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18616 if (appInfo == null) {
18617 Slog.w(TAG, "unbind backup agent for null app");
18623 synchronized(this) {
18625 if (mBackupAppName == null) {
18626 Slog.w(TAG, "Unbinding backup agent with no active backup");
18630 if (!mBackupAppName.equals(appInfo.packageName)) {
18631 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18635 // Not backing this app up any more; reset its OOM adjustment
18636 final ProcessRecord proc = mBackupTarget.app;
18637 updateOomAdjLocked(proc, true);
18638 proc.inFullBackup = false;
18640 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18642 // If the app crashed during backup, 'thread' will be null here
18643 if (proc.thread != null) {
18645 proc.thread.scheduleDestroyBackupAgent(appInfo,
18646 compatibilityInfoForPackageLocked(appInfo));
18647 } catch (Exception e) {
18648 Slog.e(TAG, "Exception when unbinding backup agent:");
18649 e.printStackTrace();
18653 mBackupTarget = null;
18654 mBackupAppName = null;
18658 if (oldBackupUid != -1) {
18659 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18660 js.removeBackingUpUid(oldBackupUid);
18664 // =========================================================
18666 // =========================================================
18668 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18669 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18672 // Easy case -- we have the app's ProcessRecord.
18673 if (record != null) {
18674 return record.info.isInstantApp();
18676 // Otherwise check with PackageManager.
18677 if (callerPackage == null) {
18678 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18679 throw new IllegalArgumentException("Calling application did not provide package name");
18681 mAppOpsService.checkPackage(uid, callerPackage);
18683 IPackageManager pm = AppGlobals.getPackageManager();
18684 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18685 } catch (RemoteException e) {
18686 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18691 boolean isPendingBroadcastProcessLocked(int pid) {
18692 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18693 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18696 void skipPendingBroadcastLocked(int pid) {
18697 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18698 for (BroadcastQueue queue : mBroadcastQueues) {
18699 queue.skipPendingBroadcastLocked(pid);
18703 // The app just attached; send any pending broadcasts that it should receive
18704 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18705 boolean didSomething = false;
18706 for (BroadcastQueue queue : mBroadcastQueues) {
18707 didSomething |= queue.sendPendingBroadcastsLocked(app);
18709 return didSomething;
18712 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18713 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18715 enforceNotIsolatedCaller("registerReceiver");
18716 ArrayList<Intent> stickyIntents = null;
18717 ProcessRecord callerApp = null;
18718 final boolean visibleToInstantApps
18719 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18722 boolean instantApp;
18723 synchronized(this) {
18724 if (caller != null) {
18725 callerApp = getRecordForAppLocked(caller);
18726 if (callerApp == null) {
18727 throw new SecurityException(
18728 "Unable to find app for caller " + caller
18729 + " (pid=" + Binder.getCallingPid()
18730 + ") when registering receiver " + receiver);
18732 if (callerApp.info.uid != SYSTEM_UID &&
18733 !callerApp.pkgList.containsKey(callerPackage) &&
18734 !"android".equals(callerPackage)) {
18735 throw new SecurityException("Given caller package " + callerPackage
18736 + " is not running in process " + callerApp);
18738 callingUid = callerApp.info.uid;
18739 callingPid = callerApp.pid;
18741 callerPackage = null;
18742 callingUid = Binder.getCallingUid();
18743 callingPid = Binder.getCallingPid();
18746 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18747 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18748 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18750 Iterator<String> actions = filter.actionsIterator();
18751 if (actions == null) {
18752 ArrayList<String> noAction = new ArrayList<String>(1);
18753 noAction.add(null);
18754 actions = noAction.iterator();
18757 // Collect stickies of users
18758 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18759 while (actions.hasNext()) {
18760 String action = actions.next();
18761 for (int id : userIds) {
18762 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18763 if (stickies != null) {
18764 ArrayList<Intent> intents = stickies.get(action);
18765 if (intents != null) {
18766 if (stickyIntents == null) {
18767 stickyIntents = new ArrayList<Intent>();
18769 stickyIntents.addAll(intents);
18776 ArrayList<Intent> allSticky = null;
18777 if (stickyIntents != null) {
18778 final ContentResolver resolver = mContext.getContentResolver();
18779 // Look for any matching sticky broadcasts...
18780 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18781 Intent intent = stickyIntents.get(i);
18782 // Don't provided intents that aren't available to instant apps.
18784 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18787 // If intent has scheme "content", it will need to acccess
18788 // provider that needs to lock mProviderMap in ActivityThread
18789 // and also it may need to wait application response, so we
18790 // cannot lock ActivityManagerService here.
18791 if (filter.match(resolver, intent, true, TAG) >= 0) {
18792 if (allSticky == null) {
18793 allSticky = new ArrayList<Intent>();
18795 allSticky.add(intent);
18800 // The first sticky in the list is returned directly back to the client.
18801 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18802 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18803 if (receiver == null) {
18807 synchronized (this) {
18808 if (callerApp != null && (callerApp.thread == null
18809 || callerApp.thread.asBinder() != caller.asBinder())) {
18810 // Original caller already died
18813 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18815 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18817 if (rl.app != null) {
18818 rl.app.receivers.add(rl);
18821 receiver.asBinder().linkToDeath(rl, 0);
18822 } catch (RemoteException e) {
18825 rl.linkedToDeath = true;
18827 mRegisteredReceivers.put(receiver.asBinder(), rl);
18828 } else if (rl.uid != callingUid) {
18829 throw new IllegalArgumentException(
18830 "Receiver requested to register for uid " + callingUid
18831 + " was previously registered for uid " + rl.uid
18832 + " callerPackage is " + callerPackage);
18833 } else if (rl.pid != callingPid) {
18834 throw new IllegalArgumentException(
18835 "Receiver requested to register for pid " + callingPid
18836 + " was previously registered for pid " + rl.pid
18837 + " callerPackage is " + callerPackage);
18838 } else if (rl.userId != userId) {
18839 throw new IllegalArgumentException(
18840 "Receiver requested to register for user " + userId
18841 + " was previously registered for user " + rl.userId
18842 + " callerPackage is " + callerPackage);
18844 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18845 permission, callingUid, userId, instantApp, visibleToInstantApps);
18847 if (!bf.debugCheck()) {
18848 Slog.w(TAG, "==> For Dynamic broadcast");
18850 mReceiverResolver.addFilter(bf);
18852 // Enqueue broadcasts for all existing stickies that match
18854 if (allSticky != null) {
18855 ArrayList receivers = new ArrayList();
18858 final int stickyCount = allSticky.size();
18859 for (int i = 0; i < stickyCount; i++) {
18860 Intent intent = allSticky.get(i);
18861 BroadcastQueue queue = broadcastQueueForIntent(intent);
18862 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18863 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18864 null, 0, null, null, false, true, true, -1);
18865 queue.enqueueParallelBroadcastLocked(r);
18866 queue.scheduleBroadcastsLocked();
18874 public void unregisterReceiver(IIntentReceiver receiver) {
18875 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18877 final long origId = Binder.clearCallingIdentity();
18879 boolean doTrim = false;
18881 synchronized(this) {
18882 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18884 final BroadcastRecord r = rl.curBroadcast;
18885 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18886 final boolean doNext = r.queue.finishReceiverLocked(
18887 r, r.resultCode, r.resultData, r.resultExtras,
18888 r.resultAbort, false);
18891 r.queue.processNextBroadcast(false);
18895 if (rl.app != null) {
18896 rl.app.receivers.remove(rl);
18898 removeReceiverLocked(rl);
18899 if (rl.linkedToDeath) {
18900 rl.linkedToDeath = false;
18901 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18906 // If we actually concluded any broadcasts, we might now be able
18907 // to trim the recipients' apps from our working set
18909 trimApplications();
18914 Binder.restoreCallingIdentity(origId);
18918 void removeReceiverLocked(ReceiverList rl) {
18919 mRegisteredReceivers.remove(rl.receiver.asBinder());
18920 for (int i = rl.size() - 1; i >= 0; i--) {
18921 mReceiverResolver.removeFilter(rl.get(i));
18925 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18926 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18927 ProcessRecord r = mLruProcesses.get(i);
18928 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18930 r.thread.dispatchPackageBroadcast(cmd, packages);
18931 } catch (RemoteException ex) {
18937 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18938 int callingUid, int[] users) {
18939 // TODO: come back and remove this assumption to triage all broadcasts
18940 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18942 List<ResolveInfo> receivers = null;
18944 HashSet<ComponentName> singleUserReceivers = null;
18945 boolean scannedFirstReceivers = false;
18946 for (int user : users) {
18947 // Skip users that have Shell restrictions, with exception of always permitted
18948 // Shell broadcasts
18949 if (callingUid == SHELL_UID
18950 && mUserController.hasUserRestriction(
18951 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18952 && !isPermittedShellBroadcast(intent)) {
18955 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18956 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18957 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18958 // If this is not the system user, we need to check for
18959 // any receivers that should be filtered out.
18960 for (int i=0; i<newReceivers.size(); i++) {
18961 ResolveInfo ri = newReceivers.get(i);
18962 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18963 newReceivers.remove(i);
18968 if (newReceivers != null && newReceivers.size() == 0) {
18969 newReceivers = null;
18971 if (receivers == null) {
18972 receivers = newReceivers;
18973 } else if (newReceivers != null) {
18974 // We need to concatenate the additional receivers
18975 // found with what we have do far. This would be easy,
18976 // but we also need to de-dup any receivers that are
18978 if (!scannedFirstReceivers) {
18979 // Collect any single user receivers we had already retrieved.
18980 scannedFirstReceivers = true;
18981 for (int i=0; i<receivers.size(); i++) {
18982 ResolveInfo ri = receivers.get(i);
18983 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18984 ComponentName cn = new ComponentName(
18985 ri.activityInfo.packageName, ri.activityInfo.name);
18986 if (singleUserReceivers == null) {
18987 singleUserReceivers = new HashSet<ComponentName>();
18989 singleUserReceivers.add(cn);
18993 // Add the new results to the existing results, tracking
18994 // and de-dupping single user receivers.
18995 for (int i=0; i<newReceivers.size(); i++) {
18996 ResolveInfo ri = newReceivers.get(i);
18997 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18998 ComponentName cn = new ComponentName(
18999 ri.activityInfo.packageName, ri.activityInfo.name);
19000 if (singleUserReceivers == null) {
19001 singleUserReceivers = new HashSet<ComponentName>();
19003 if (!singleUserReceivers.contains(cn)) {
19004 singleUserReceivers.add(cn);
19013 } catch (RemoteException ex) {
19014 // pm is in same process, this will never happen.
19019 private boolean isPermittedShellBroadcast(Intent intent) {
19020 // remote bugreport should always be allowed to be taken
19021 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19024 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19025 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19026 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19027 // Don't yell about broadcasts sent via shell
19031 final String action = intent.getAction();
19032 if (isProtectedBroadcast
19033 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19034 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19035 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19036 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19037 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19038 || Intent.ACTION_MASTER_CLEAR.equals(action)
19039 || Intent.ACTION_FACTORY_RESET.equals(action)
19040 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19041 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19042 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19043 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19044 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19045 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19046 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19047 // Broadcast is either protected, or it's a public action that
19048 // we've relaxed, so it's fine for system internals to send.
19052 // This broadcast may be a problem... but there are often system components that
19053 // want to send an internal broadcast to themselves, which is annoying to have to
19054 // explicitly list each action as a protected broadcast, so we will check for that
19055 // one safe case and allow it: an explicit broadcast, only being received by something
19056 // that has protected itself.
19057 if (receivers != null && receivers.size() > 0
19058 && (intent.getPackage() != null || intent.getComponent() != null)) {
19059 boolean allProtected = true;
19060 for (int i = receivers.size()-1; i >= 0; i--) {
19061 Object target = receivers.get(i);
19062 if (target instanceof ResolveInfo) {
19063 ResolveInfo ri = (ResolveInfo)target;
19064 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19065 allProtected = false;
19069 BroadcastFilter bf = (BroadcastFilter)target;
19070 if (bf.requiredPermission == null) {
19071 allProtected = false;
19076 if (allProtected) {
19082 // The vast majority of broadcasts sent from system internals
19083 // should be protected to avoid security holes, so yell loudly
19084 // to ensure we examine these cases.
19085 if (callerApp != null) {
19086 Log.wtf(TAG, "Sending non-protected broadcast " + action
19087 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19090 Log.wtf(TAG, "Sending non-protected broadcast " + action
19091 + " from system uid " + UserHandle.formatUid(callingUid)
19092 + " pkg " + callerPackage,
19097 final int broadcastIntentLocked(ProcessRecord callerApp,
19098 String callerPackage, Intent intent, String resolvedType,
19099 IIntentReceiver resultTo, int resultCode, String resultData,
19100 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19101 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19102 intent = new Intent(intent);
19104 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19105 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19106 if (callerInstantApp) {
19107 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19110 // By default broadcasts do not go to stopped apps.
19111 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19113 // If we have not finished booting, don't allow this to launch new processes.
19114 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19115 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19118 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19119 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19120 + " ordered=" + ordered + " userid=" + userId);
19121 if ((resultTo != null) && !ordered) {
19122 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19125 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19126 ALLOW_NON_FULL, "broadcast", callerPackage);
19128 // Make sure that the user who is receiving this broadcast is running.
19129 // If not, we will just skip it. Make an exception for shutdown broadcasts
19130 // and upgrade steps.
19132 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19133 if ((callingUid != SYSTEM_UID
19134 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19135 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19136 Slog.w(TAG, "Skipping broadcast of " + intent
19137 + ": user " + userId + " is stopped");
19138 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19142 BroadcastOptions brOptions = null;
19143 if (bOptions != null) {
19144 brOptions = new BroadcastOptions(bOptions);
19145 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19146 // See if the caller is allowed to do this. Note we are checking against
19147 // the actual real caller (not whoever provided the operation as say a
19148 // PendingIntent), because that who is actually supplied the arguments.
19149 if (checkComponentPermission(
19150 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19151 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19152 != PackageManager.PERMISSION_GRANTED) {
19153 String msg = "Permission Denial: " + intent.getAction()
19154 + " broadcast from " + callerPackage + " (pid=" + callingPid
19155 + ", uid=" + callingUid + ")"
19157 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19159 throw new SecurityException(msg);
19164 // Verify that protected broadcasts are only being sent by system code,
19165 // and that system code is only sending protected broadcasts.
19166 final String action = intent.getAction();
19167 final boolean isProtectedBroadcast;
19169 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19170 } catch (RemoteException e) {
19171 Slog.w(TAG, "Remote exception", e);
19172 return ActivityManager.BROADCAST_SUCCESS;
19175 final boolean isCallerSystem;
19176 switch (UserHandle.getAppId(callingUid)) {
19180 case BLUETOOTH_UID:
19182 isCallerSystem = true;
19185 isCallerSystem = (callerApp != null) && callerApp.persistent;
19189 // First line security check before anything else: stop non-system apps from
19190 // sending protected broadcasts.
19191 if (!isCallerSystem) {
19192 if (isProtectedBroadcast) {
19193 String msg = "Permission Denial: not allowed to send broadcast "
19194 + action + " from pid="
19195 + callingPid + ", uid=" + callingUid;
19197 throw new SecurityException(msg);
19199 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19200 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19201 // Special case for compatibility: we don't want apps to send this,
19202 // but historically it has not been protected and apps may be using it
19203 // to poke their own app widget. So, instead of making it protected,
19204 // just limit it to the caller.
19205 if (callerPackage == null) {
19206 String msg = "Permission Denial: not allowed to send broadcast "
19207 + action + " from unknown caller.";
19209 throw new SecurityException(msg);
19210 } else if (intent.getComponent() != null) {
19211 // They are good enough to send to an explicit component... verify
19212 // it is being sent to the calling app.
19213 if (!intent.getComponent().getPackageName().equals(
19215 String msg = "Permission Denial: not allowed to send broadcast "
19217 + intent.getComponent().getPackageName() + " from "
19220 throw new SecurityException(msg);
19223 // Limit broadcast to their own package.
19224 intent.setPackage(callerPackage);
19229 if (action != null) {
19230 if (getBackgroundLaunchBroadcasts().contains(action)) {
19231 if (DEBUG_BACKGROUND_CHECK) {
19232 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19234 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19238 case Intent.ACTION_UID_REMOVED:
19239 case Intent.ACTION_PACKAGE_REMOVED:
19240 case Intent.ACTION_PACKAGE_CHANGED:
19241 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19242 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19243 case Intent.ACTION_PACKAGES_SUSPENDED:
19244 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19245 // Handle special intents: if this broadcast is from the package
19246 // manager about a package being removed, we need to remove all of
19247 // its activities from the history stack.
19248 if (checkComponentPermission(
19249 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19250 callingPid, callingUid, -1, true)
19251 != PackageManager.PERMISSION_GRANTED) {
19252 String msg = "Permission Denial: " + intent.getAction()
19253 + " broadcast from " + callerPackage + " (pid=" + callingPid
19254 + ", uid=" + callingUid + ")"
19256 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19258 throw new SecurityException(msg);
19261 case Intent.ACTION_UID_REMOVED:
19262 final int uid = getUidFromIntent(intent);
19264 mBatteryStatsService.removeUid(uid);
19265 mAppOpsService.uidRemoved(uid);
19268 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19269 // If resources are unavailable just force stop all those packages
19270 // and flush the attribute cache as well.
19272 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19273 if (list != null && list.length > 0) {
19274 for (int i = 0; i < list.length; i++) {
19275 forceStopPackageLocked(list[i], -1, false, true, true,
19276 false, false, userId, "storage unmount");
19278 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19279 sendPackageBroadcastLocked(
19280 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19284 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19285 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19287 case Intent.ACTION_PACKAGE_REMOVED:
19288 case Intent.ACTION_PACKAGE_CHANGED:
19289 Uri data = intent.getData();
19291 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19292 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19293 final boolean replacing =
19294 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19295 final boolean killProcess =
19296 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19297 final boolean fullUninstall = removed && !replacing;
19300 forceStopPackageLocked(ssp, UserHandle.getAppId(
19301 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19302 false, true, true, false, fullUninstall, userId,
19303 removed ? "pkg removed" : "pkg changed");
19305 final int cmd = killProcess
19306 ? ApplicationThreadConstants.PACKAGE_REMOVED
19307 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19308 sendPackageBroadcastLocked(cmd,
19309 new String[] {ssp}, userId);
19310 if (fullUninstall) {
19311 mAppOpsService.packageRemoved(
19312 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19314 // Remove all permissions granted from/to this package
19315 removeUriPermissionsForPackageLocked(ssp, userId, true);
19317 removeTasksByPackageNameLocked(ssp, userId);
19319 mServices.forceStopPackageLocked(ssp, userId);
19321 // Hide the "unsupported display" dialog if necessary.
19322 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19323 mUnsupportedDisplaySizeDialog.getPackageName())) {
19324 mUnsupportedDisplaySizeDialog.dismiss();
19325 mUnsupportedDisplaySizeDialog = null;
19327 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19328 mBatteryStatsService.notePackageUninstalled(ssp);
19332 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19333 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19334 userId, ProcessList.INVALID_ADJ,
19335 false, true, true, false, "change " + ssp);
19337 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19338 intent.getStringArrayExtra(
19339 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19343 case Intent.ACTION_PACKAGES_SUSPENDED:
19344 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19345 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19346 intent.getAction());
19347 final String[] packageNames = intent.getStringArrayExtra(
19348 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19349 final int userHandle = intent.getIntExtra(
19350 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19352 synchronized(ActivityManagerService.this) {
19353 mRecentTasks.onPackagesSuspendedChanged(
19354 packageNames, suspended, userHandle);
19359 case Intent.ACTION_PACKAGE_REPLACED:
19361 final Uri data = intent.getData();
19363 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19364 ApplicationInfo aInfo = null;
19366 aInfo = AppGlobals.getPackageManager()
19367 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19368 } catch (RemoteException ignore) {}
19369 if (aInfo == null) {
19370 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19371 + " ssp=" + ssp + " data=" + data);
19372 return ActivityManager.BROADCAST_SUCCESS;
19374 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19375 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19376 new String[] {ssp}, userId);
19380 case Intent.ACTION_PACKAGE_ADDED:
19382 // Special case for adding a package: by default turn on compatibility mode.
19383 Uri data = intent.getData();
19385 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19386 final boolean replacing =
19387 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19388 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19391 ApplicationInfo ai = AppGlobals.getPackageManager().
19392 getApplicationInfo(ssp, 0, 0);
19393 mBatteryStatsService.notePackageInstalled(ssp,
19394 ai != null ? ai.versionCode : 0);
19395 } catch (RemoteException e) {
19400 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19402 Uri data = intent.getData();
19404 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19405 // Hide the "unsupported display" dialog if necessary.
19406 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19407 mUnsupportedDisplaySizeDialog.getPackageName())) {
19408 mUnsupportedDisplaySizeDialog.dismiss();
19409 mUnsupportedDisplaySizeDialog = null;
19411 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19415 case Intent.ACTION_TIMEZONE_CHANGED:
19416 // If this is the time zone changed action, queue up a message that will reset
19417 // the timezone of all currently running processes. This message will get
19418 // queued up before the broadcast happens.
19419 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19421 case Intent.ACTION_TIME_CHANGED:
19422 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19423 // the tri-state value it may contain and "unknown".
19424 // For convenience we re-use the Intent extra values.
19425 final int NO_EXTRA_VALUE_FOUND = -1;
19426 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19427 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19428 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19429 // Only send a message if the time preference is available.
19430 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19431 Message updateTimePreferenceMsg =
19432 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19433 timeFormatPreferenceMsgValue, 0);
19434 mHandler.sendMessage(updateTimePreferenceMsg);
19436 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19437 synchronized (stats) {
19438 stats.noteCurrentTimeChangedLocked();
19441 case Intent.ACTION_CLEAR_DNS_CACHE:
19442 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19444 case Proxy.PROXY_CHANGE_ACTION:
19445 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19446 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19448 case android.hardware.Camera.ACTION_NEW_PICTURE:
19449 case android.hardware.Camera.ACTION_NEW_VIDEO:
19450 // In N we just turned these off; in O we are turing them back on partly,
19451 // only for registered receivers. This will still address the main problem
19452 // (a spam of apps waking up when a picture is taken putting significant
19453 // memory pressure on the system at a bad point), while still allowing apps
19454 // that are already actively running to know about this happening.
19455 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19457 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19458 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19460 case "com.android.launcher.action.INSTALL_SHORTCUT":
19461 // As of O, we no longer support this broadcasts, even for pre-O apps.
19462 // Apps should now be using ShortcutManager.pinRequestShortcut().
19463 Log.w(TAG, "Broadcast " + action
19464 + " no longer supported. It will not be delivered.");
19465 return ActivityManager.BROADCAST_SUCCESS;
19468 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19469 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19470 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19471 final int uid = getUidFromIntent(intent);
19473 final UidRecord uidRec = mActiveUids.get(uid);
19474 if (uidRec != null) {
19475 uidRec.updateHasInternetPermission();
19481 // Add to the sticky list if requested.
19483 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19484 callingPid, callingUid)
19485 != PackageManager.PERMISSION_GRANTED) {
19486 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19487 + callingPid + ", uid=" + callingUid
19488 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19490 throw new SecurityException(msg);
19492 if (requiredPermissions != null && requiredPermissions.length > 0) {
19493 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19494 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19495 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19497 if (intent.getComponent() != null) {
19498 throw new SecurityException(
19499 "Sticky broadcasts can't target a specific component");
19501 // We use userId directly here, since the "all" target is maintained
19502 // as a separate set of sticky broadcasts.
19503 if (userId != UserHandle.USER_ALL) {
19504 // But first, if this is not a broadcast to all users, then
19505 // make sure it doesn't conflict with an existing broadcast to
19507 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19508 UserHandle.USER_ALL);
19509 if (stickies != null) {
19510 ArrayList<Intent> list = stickies.get(intent.getAction());
19511 if (list != null) {
19512 int N = list.size();
19514 for (i=0; i<N; i++) {
19515 if (intent.filterEquals(list.get(i))) {
19516 throw new IllegalArgumentException(
19517 "Sticky broadcast " + intent + " for user "
19518 + userId + " conflicts with existing global broadcast");
19524 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19525 if (stickies == null) {
19526 stickies = new ArrayMap<>();
19527 mStickyBroadcasts.put(userId, stickies);
19529 ArrayList<Intent> list = stickies.get(intent.getAction());
19530 if (list == null) {
19531 list = new ArrayList<>();
19532 stickies.put(intent.getAction(), list);
19534 final int stickiesCount = list.size();
19536 for (i = 0; i < stickiesCount; i++) {
19537 if (intent.filterEquals(list.get(i))) {
19538 // This sticky already exists, replace it.
19539 list.set(i, new Intent(intent));
19543 if (i >= stickiesCount) {
19544 list.add(new Intent(intent));
19549 if (userId == UserHandle.USER_ALL) {
19550 // Caller wants broadcast to go to all started users.
19551 users = mUserController.getStartedUserArrayLocked();
19553 // Caller wants broadcast to go to one specific user.
19554 users = new int[] {userId};
19557 // Figure out who all will receive this broadcast.
19558 List receivers = null;
19559 List<BroadcastFilter> registeredReceivers = null;
19560 // Need to resolve the intent to interested receivers...
19561 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19563 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19565 if (intent.getComponent() == null) {
19566 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19567 // Query one target user at a time, excluding shell-restricted users
19568 for (int i = 0; i < users.length; i++) {
19569 if (mUserController.hasUserRestriction(
19570 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19573 List<BroadcastFilter> registeredReceiversForUser =
19574 mReceiverResolver.queryIntent(intent,
19575 resolvedType, false /*defaultOnly*/, users[i]);
19576 if (registeredReceivers == null) {
19577 registeredReceivers = registeredReceiversForUser;
19578 } else if (registeredReceiversForUser != null) {
19579 registeredReceivers.addAll(registeredReceiversForUser);
19583 registeredReceivers = mReceiverResolver.queryIntent(intent,
19584 resolvedType, false /*defaultOnly*/, userId);
19588 final boolean replacePending =
19589 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19591 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19592 + " replacePending=" + replacePending);
19594 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19595 if (!ordered && NR > 0) {
19596 // If we are not serializing this broadcast, then send the
19597 // registered receivers separately so they don't wait for the
19598 // components to be launched.
19599 if (isCallerSystem) {
19600 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19601 isProtectedBroadcast, registeredReceivers);
19603 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19604 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19605 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19606 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19607 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19608 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19609 final boolean replaced = replacePending
19610 && (queue.replaceParallelBroadcastLocked(r) != null);
19611 // Note: We assume resultTo is null for non-ordered broadcasts.
19613 queue.enqueueParallelBroadcastLocked(r);
19614 queue.scheduleBroadcastsLocked();
19616 registeredReceivers = null;
19620 // Merge into one list.
19622 if (receivers != null) {
19623 // A special case for PACKAGE_ADDED: do not allow the package
19624 // being added to see this broadcast. This prevents them from
19625 // using this as a back door to get run as soon as they are
19626 // installed. Maybe in the future we want to have a special install
19627 // broadcast or such for apps, but we'd like to deliberately make
19629 String skipPackages[] = null;
19630 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19631 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19632 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19633 Uri data = intent.getData();
19634 if (data != null) {
19635 String pkgName = data.getSchemeSpecificPart();
19636 if (pkgName != null) {
19637 skipPackages = new String[] { pkgName };
19640 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19641 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19643 if (skipPackages != null && (skipPackages.length > 0)) {
19644 for (String skipPackage : skipPackages) {
19645 if (skipPackage != null) {
19646 int NT = receivers.size();
19647 for (int it=0; it<NT; it++) {
19648 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19649 if (curt.activityInfo.packageName.equals(skipPackage)) {
19650 receivers.remove(it);
19659 int NT = receivers != null ? receivers.size() : 0;
19661 ResolveInfo curt = null;
19662 BroadcastFilter curr = null;
19663 while (it < NT && ir < NR) {
19664 if (curt == null) {
19665 curt = (ResolveInfo)receivers.get(it);
19667 if (curr == null) {
19668 curr = registeredReceivers.get(ir);
19670 if (curr.getPriority() >= curt.priority) {
19671 // Insert this broadcast record into the final list.
19672 receivers.add(it, curr);
19678 // Skip to the next ResolveInfo in the final list.
19685 if (receivers == null) {
19686 receivers = new ArrayList();
19688 receivers.add(registeredReceivers.get(ir));
19692 if (isCallerSystem) {
19693 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19694 isProtectedBroadcast, receivers);
19697 if ((receivers != null && receivers.size() > 0)
19698 || resultTo != null) {
19699 BroadcastQueue queue = broadcastQueueForIntent(intent);
19700 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19701 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19702 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19703 resultData, resultExtras, ordered, sticky, false, userId);
19705 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19706 + ": prev had " + queue.mOrderedBroadcasts.size());
19707 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19708 "Enqueueing broadcast " + r.intent.getAction());
19710 final BroadcastRecord oldRecord =
19711 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19712 if (oldRecord != null) {
19713 // Replaced, fire the result-to receiver.
19714 if (oldRecord.resultTo != null) {
19715 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19717 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19719 Activity.RESULT_CANCELED, null, null,
19720 false, false, oldRecord.userId);
19721 } catch (RemoteException e) {
19722 Slog.w(TAG, "Failure ["
19723 + queue.mQueueName + "] sending broadcast result of "
19729 queue.enqueueOrderedBroadcastLocked(r);
19730 queue.scheduleBroadcastsLocked();
19733 // There was nobody interested in the broadcast, but we still want to record
19734 // that it happened.
19735 if (intent.getComponent() == null && intent.getPackage() == null
19736 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19737 // This was an implicit broadcast... let's record it for posterity.
19738 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19742 return ActivityManager.BROADCAST_SUCCESS;
19746 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19748 private int getUidFromIntent(Intent intent) {
19749 if (intent == null) {
19752 final Bundle intentExtras = intent.getExtras();
19753 return intent.hasExtra(Intent.EXTRA_UID)
19754 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19757 final void rotateBroadcastStatsIfNeededLocked() {
19758 final long now = SystemClock.elapsedRealtime();
19759 if (mCurBroadcastStats == null ||
19760 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19761 mLastBroadcastStats = mCurBroadcastStats;
19762 if (mLastBroadcastStats != null) {
19763 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19764 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19766 mCurBroadcastStats = new BroadcastStats();
19770 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19771 int skipCount, long dispatchTime) {
19772 rotateBroadcastStatsIfNeededLocked();
19773 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19776 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19777 rotateBroadcastStatsIfNeededLocked();
19778 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19781 final Intent verifyBroadcastLocked(Intent intent) {
19782 // Refuse possible leaked file descriptors
19783 if (intent != null && intent.hasFileDescriptors() == true) {
19784 throw new IllegalArgumentException("File descriptors passed in Intent");
19787 int flags = intent.getFlags();
19789 if (!mProcessesReady) {
19790 // if the caller really truly claims to know what they're doing, go
19791 // ahead and allow the broadcast without launching any receivers
19792 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19793 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19794 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19795 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19796 + " before boot completion");
19797 throw new IllegalStateException("Cannot broadcast before boot completed");
19801 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19802 throw new IllegalArgumentException(
19803 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19806 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19807 switch (Binder.getCallingUid()) {
19812 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19813 + Binder.getCallingUid());
19814 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19822 public final int broadcastIntent(IApplicationThread caller,
19823 Intent intent, String resolvedType, IIntentReceiver resultTo,
19824 int resultCode, String resultData, Bundle resultExtras,
19825 String[] requiredPermissions, int appOp, Bundle bOptions,
19826 boolean serialized, boolean sticky, int userId) {
19827 enforceNotIsolatedCaller("broadcastIntent");
19828 synchronized(this) {
19829 intent = verifyBroadcastLocked(intent);
19831 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19832 final int callingPid = Binder.getCallingPid();
19833 final int callingUid = Binder.getCallingUid();
19834 final long origId = Binder.clearCallingIdentity();
19835 int res = broadcastIntentLocked(callerApp,
19836 callerApp != null ? callerApp.info.packageName : null,
19837 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19838 requiredPermissions, appOp, bOptions, serialized, sticky,
19839 callingPid, callingUid, userId);
19840 Binder.restoreCallingIdentity(origId);
19846 int broadcastIntentInPackage(String packageName, int uid,
19847 Intent intent, String resolvedType, IIntentReceiver resultTo,
19848 int resultCode, String resultData, Bundle resultExtras,
19849 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19851 synchronized(this) {
19852 intent = verifyBroadcastLocked(intent);
19854 final long origId = Binder.clearCallingIdentity();
19855 String[] requiredPermissions = requiredPermission == null ? null
19856 : new String[] {requiredPermission};
19857 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19858 resultTo, resultCode, resultData, resultExtras,
19859 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19860 sticky, -1, uid, userId);
19861 Binder.restoreCallingIdentity(origId);
19866 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19867 // Refuse possible leaked file descriptors
19868 if (intent != null && intent.hasFileDescriptors() == true) {
19869 throw new IllegalArgumentException("File descriptors passed in Intent");
19872 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19873 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19875 synchronized(this) {
19876 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19877 != PackageManager.PERMISSION_GRANTED) {
19878 String msg = "Permission Denial: unbroadcastIntent() from pid="
19879 + Binder.getCallingPid()
19880 + ", uid=" + Binder.getCallingUid()
19881 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19883 throw new SecurityException(msg);
19885 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19886 if (stickies != null) {
19887 ArrayList<Intent> list = stickies.get(intent.getAction());
19888 if (list != null) {
19889 int N = list.size();
19891 for (i=0; i<N; i++) {
19892 if (intent.filterEquals(list.get(i))) {
19897 if (list.size() <= 0) {
19898 stickies.remove(intent.getAction());
19901 if (stickies.size() <= 0) {
19902 mStickyBroadcasts.remove(userId);
19908 void backgroundServicesFinishedLocked(int userId) {
19909 for (BroadcastQueue queue : mBroadcastQueues) {
19910 queue.backgroundServicesFinishedLocked(userId);
19914 public void finishReceiver(IBinder who, int resultCode, String resultData,
19915 Bundle resultExtras, boolean resultAbort, int flags) {
19916 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19918 // Refuse possible leaked file descriptors
19919 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19920 throw new IllegalArgumentException("File descriptors passed in Bundle");
19923 final long origId = Binder.clearCallingIdentity();
19925 boolean doNext = false;
19928 synchronized(this) {
19929 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19930 ? mFgBroadcastQueue : mBgBroadcastQueue;
19931 r = queue.getMatchingOrderedReceiver(who);
19933 doNext = r.queue.finishReceiverLocked(r, resultCode,
19934 resultData, resultExtras, resultAbort, true);
19939 r.queue.processNextBroadcast(false);
19941 trimApplications();
19943 Binder.restoreCallingIdentity(origId);
19947 // =========================================================
19949 // =========================================================
19951 public boolean startInstrumentation(ComponentName className,
19952 String profileFile, int flags, Bundle arguments,
19953 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19954 int userId, String abiOverride) {
19955 enforceNotIsolatedCaller("startInstrumentation");
19956 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19957 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19958 // Refuse possible leaked file descriptors
19959 if (arguments != null && arguments.hasFileDescriptors()) {
19960 throw new IllegalArgumentException("File descriptors passed in Bundle");
19963 synchronized(this) {
19964 InstrumentationInfo ii = null;
19965 ApplicationInfo ai = null;
19967 ii = mContext.getPackageManager().getInstrumentationInfo(
19968 className, STOCK_PM_FLAGS);
19969 ai = AppGlobals.getPackageManager().getApplicationInfo(
19970 ii.targetPackage, STOCK_PM_FLAGS, userId);
19971 } catch (PackageManager.NameNotFoundException e) {
19972 } catch (RemoteException e) {
19975 reportStartInstrumentationFailureLocked(watcher, className,
19976 "Unable to find instrumentation info for: " + className);
19980 reportStartInstrumentationFailureLocked(watcher, className,
19981 "Unable to find instrumentation target package: " + ii.targetPackage);
19984 if (!ai.hasCode()) {
19985 reportStartInstrumentationFailureLocked(watcher, className,
19986 "Instrumentation target has no code: " + ii.targetPackage);
19990 int match = mContext.getPackageManager().checkSignatures(
19991 ii.targetPackage, ii.packageName);
19992 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19993 String msg = "Permission Denial: starting instrumentation "
19994 + className + " from pid="
19995 + Binder.getCallingPid()
19996 + ", uid=" + Binder.getCallingPid()
19997 + " not allowed because package " + ii.packageName
19998 + " does not have a signature matching the target "
19999 + ii.targetPackage;
20000 reportStartInstrumentationFailureLocked(watcher, className, msg);
20001 throw new SecurityException(msg);
20004 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20005 activeInstr.mClass = className;
20006 String defProcess = ai.processName;;
20007 if (ii.targetProcesses == null) {
20008 activeInstr.mTargetProcesses = new String[]{ai.processName};
20009 } else if (ii.targetProcesses.equals("*")) {
20010 activeInstr.mTargetProcesses = new String[0];
20012 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20013 defProcess = activeInstr.mTargetProcesses[0];
20015 activeInstr.mTargetInfo = ai;
20016 activeInstr.mProfileFile = profileFile;
20017 activeInstr.mArguments = arguments;
20018 activeInstr.mWatcher = watcher;
20019 activeInstr.mUiAutomationConnection = uiAutomationConnection;
20020 activeInstr.mResultClass = className;
20022 final long origId = Binder.clearCallingIdentity();
20023 // Instrumentation can kill and relaunch even persistent processes
20024 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20026 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20027 app.instr = activeInstr;
20028 activeInstr.mFinished = false;
20029 activeInstr.mRunningProcesses.add(app);
20030 if (!mActiveInstrumentation.contains(activeInstr)) {
20031 mActiveInstrumentation.add(activeInstr);
20033 Binder.restoreCallingIdentity(origId);
20040 * Report errors that occur while attempting to start Instrumentation. Always writes the
20041 * error to the logs, but if somebody is watching, send the report there too. This enables
20042 * the "am" command to report errors with more information.
20044 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
20045 * @param cn The component name of the instrumentation.
20046 * @param report The error report.
20048 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20049 ComponentName cn, String report) {
20050 Slog.w(TAG, report);
20051 if (watcher != null) {
20052 Bundle results = new Bundle();
20053 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20054 results.putString("Error", report);
20055 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20059 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20060 if (app.instr == null) {
20061 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20065 if (!app.instr.mFinished && results != null) {
20066 if (app.instr.mCurResults == null) {
20067 app.instr.mCurResults = new Bundle(results);
20069 app.instr.mCurResults.putAll(results);
20074 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20075 int userId = UserHandle.getCallingUserId();
20076 // Refuse possible leaked file descriptors
20077 if (results != null && results.hasFileDescriptors()) {
20078 throw new IllegalArgumentException("File descriptors passed in Intent");
20081 synchronized(this) {
20082 ProcessRecord app = getRecordForAppLocked(target);
20084 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20087 final long origId = Binder.clearCallingIdentity();
20088 addInstrumentationResultsLocked(app, results);
20089 Binder.restoreCallingIdentity(origId);
20093 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20094 if (app.instr == null) {
20095 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20099 if (!app.instr.mFinished) {
20100 if (app.instr.mWatcher != null) {
20101 Bundle finalResults = app.instr.mCurResults;
20102 if (finalResults != null) {
20103 if (app.instr.mCurResults != null && results != null) {
20104 finalResults.putAll(results);
20107 finalResults = results;
20109 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20110 app.instr.mClass, resultCode, finalResults);
20113 // Can't call out of the system process with a lock held, so post a message.
20114 if (app.instr.mUiAutomationConnection != null) {
20115 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20116 app.instr.mUiAutomationConnection).sendToTarget();
20118 app.instr.mFinished = true;
20121 app.instr.removeProcess(app);
20124 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20128 public void finishInstrumentation(IApplicationThread target,
20129 int resultCode, Bundle results) {
20130 int userId = UserHandle.getCallingUserId();
20131 // Refuse possible leaked file descriptors
20132 if (results != null && results.hasFileDescriptors()) {
20133 throw new IllegalArgumentException("File descriptors passed in Intent");
20136 synchronized(this) {
20137 ProcessRecord app = getRecordForAppLocked(target);
20139 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20142 final long origId = Binder.clearCallingIdentity();
20143 finishInstrumentationLocked(app, resultCode, results);
20144 Binder.restoreCallingIdentity(origId);
20148 // =========================================================
20150 // =========================================================
20152 public ConfigurationInfo getDeviceConfigurationInfo() {
20153 ConfigurationInfo config = new ConfigurationInfo();
20154 synchronized (this) {
20155 final Configuration globalConfig = getGlobalConfiguration();
20156 config.reqTouchScreen = globalConfig.touchscreen;
20157 config.reqKeyboardType = globalConfig.keyboard;
20158 config.reqNavigation = globalConfig.navigation;
20159 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20160 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20161 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20163 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20164 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20165 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20167 config.reqGlEsVersion = GL_ES_VERSION;
20172 ActivityStack getFocusedStack() {
20173 return mStackSupervisor.getFocusedStack();
20177 public int getFocusedStackId() throws RemoteException {
20178 ActivityStack focusedStack = getFocusedStack();
20179 if (focusedStack != null) {
20180 return focusedStack.getStackId();
20185 public Configuration getConfiguration() {
20187 synchronized(this) {
20188 ci = new Configuration(getGlobalConfiguration());
20189 ci.userSetLocale = false;
20195 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20196 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20197 synchronized (this) {
20198 mSuppressResizeConfigChanges = suppress;
20203 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20204 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20205 * activity and clearing the task at the same time.
20208 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20209 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20210 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20211 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20213 synchronized (this) {
20214 final long origId = Binder.clearCallingIdentity();
20216 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20218 Binder.restoreCallingIdentity(origId);
20224 public void updatePersistentConfiguration(Configuration values) {
20225 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20226 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20227 if (values == null) {
20228 throw new NullPointerException("Configuration must not be null");
20231 int userId = UserHandle.getCallingUserId();
20233 synchronized(this) {
20234 updatePersistentConfigurationLocked(values, userId);
20238 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20239 final long origId = Binder.clearCallingIdentity();
20241 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20243 Binder.restoreCallingIdentity(origId);
20247 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20248 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20249 FONT_SCALE, 1.0f, userId);
20251 synchronized (this) {
20252 if (getGlobalConfiguration().fontScale == scaleFactor) {
20256 final Configuration configuration
20257 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20258 configuration.fontScale = scaleFactor;
20259 updatePersistentConfigurationLocked(configuration, userId);
20263 private void enforceWriteSettingsPermission(String func) {
20264 int uid = Binder.getCallingUid();
20265 if (uid == ROOT_UID) {
20269 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20270 Settings.getPackageNameForUid(mContext, uid), false)) {
20274 String msg = "Permission Denial: " + func + " from pid="
20275 + Binder.getCallingPid()
20277 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20279 throw new SecurityException(msg);
20283 public boolean updateConfiguration(Configuration values) {
20284 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20286 synchronized(this) {
20287 if (values == null && mWindowManager != null) {
20288 // sentinel: fetch the current configuration from the window manager
20289 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20292 if (mWindowManager != null) {
20293 // Update OOM levels based on display size.
20294 mProcessList.applyDisplaySize(mWindowManager);
20297 final long origId = Binder.clearCallingIdentity();
20299 if (values != null) {
20300 Settings.System.clearConfiguration(values);
20302 updateConfigurationLocked(values, null, false, false /* persistent */,
20303 UserHandle.USER_NULL, false /* deferResume */,
20304 mTmpUpdateConfigurationResult);
20305 return mTmpUpdateConfigurationResult.changes != 0;
20307 Binder.restoreCallingIdentity(origId);
20312 void updateUserConfigurationLocked() {
20313 final Configuration configuration = new Configuration(getGlobalConfiguration());
20314 final int currentUserId = mUserController.getCurrentUserIdLocked();
20315 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20316 currentUserId, Settings.System.canWrite(mContext));
20317 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20318 false /* persistent */, currentUserId, false /* deferResume */);
20321 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20322 boolean initLocale) {
20323 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20326 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20327 boolean initLocale, boolean deferResume) {
20328 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20329 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20330 UserHandle.USER_NULL, deferResume);
20333 // To cache the list of supported system locales
20334 private String[] mSupportedSystemLocales = null;
20336 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20337 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20338 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20339 deferResume, null /* result */);
20343 * Do either or both things: (1) change the current configuration, and (2)
20344 * make sure the given activity is running with the (now) current
20345 * configuration. Returns true if the activity has been left running, or
20346 * false if <var>starting</var> is being destroyed to match the new
20349 * @param userId is only used when persistent parameter is set to true to persist configuration
20350 * for that particular user
20352 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20353 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20354 UpdateConfigurationResult result) {
20356 boolean kept = true;
20358 if (mWindowManager != null) {
20359 mWindowManager.deferSurfaceLayout();
20362 if (values != null) {
20363 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20367 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20369 if (mWindowManager != null) {
20370 mWindowManager.continueSurfaceLayout();
20374 if (result != null) {
20375 result.changes = changes;
20376 result.activityRelaunched = !kept;
20381 /** Update default (global) configuration and notify listeners about changes. */
20382 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20383 boolean persistent, int userId, boolean deferResume) {
20384 mTempConfig.setTo(getGlobalConfiguration());
20385 final int changes = mTempConfig.updateFrom(values);
20386 if (changes == 0) {
20387 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20388 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20389 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20390 // (even if there are no actual changes) to unfreeze the window.
20391 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20395 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20396 "Updating global configuration to: " + values);
20398 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20400 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20401 final LocaleList locales = values.getLocales();
20402 int bestLocaleIndex = 0;
20403 if (locales.size() > 1) {
20404 if (mSupportedSystemLocales == null) {
20405 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20407 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20409 SystemProperties.set("persist.sys.locale",
20410 locales.get(bestLocaleIndex).toLanguageTag());
20411 LocaleList.setDefault(locales, bestLocaleIndex);
20412 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20413 locales.get(bestLocaleIndex)));
20416 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20417 mTempConfig.seq = mConfigurationSeq;
20419 // Update stored global config and notify everyone about the change.
20420 mStackSupervisor.onConfigurationChanged(mTempConfig);
20422 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20423 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20424 mUsageStatsService.reportConfigurationChange(mTempConfig,
20425 mUserController.getCurrentUserIdLocked());
20427 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20428 mShowDialogs = shouldShowDialogs(mTempConfig);
20430 AttributeCache ac = AttributeCache.instance();
20432 ac.updateConfiguration(mTempConfig);
20435 // Make sure all resources in our process are updated right now, so that anyone who is going
20436 // to retrieve resource values after we return will be sure to get the new ones. This is
20437 // especially important during boot, where the first config change needs to guarantee all
20438 // resources have that config before following boot code is executed.
20439 mSystemThread.applyConfigurationToResources(mTempConfig);
20441 // We need another copy of global config because we're scheduling some calls instead of
20442 // running them in place. We need to be sure that object we send will be handled unchanged.
20443 final Configuration configCopy = new Configuration(mTempConfig);
20444 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20445 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20446 msg.obj = configCopy;
20448 mHandler.sendMessage(msg);
20451 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20452 ProcessRecord app = mLruProcesses.get(i);
20454 if (app.thread != null) {
20455 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20456 + app.processName + " new config " + configCopy);
20457 app.thread.scheduleConfigurationChanged(configCopy);
20459 } catch (Exception e) {
20463 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20464 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20465 | Intent.FLAG_RECEIVER_FOREGROUND
20466 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20467 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20468 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20469 UserHandle.USER_ALL);
20470 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20471 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20472 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20473 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20474 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20475 if (initLocale || !mProcessesReady) {
20476 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20478 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20479 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20480 UserHandle.USER_ALL);
20483 // Override configuration of the default display duplicates global config, so we need to
20484 // update it also. This will also notify WindowManager about changes.
20485 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20492 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20493 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20495 synchronized (this) {
20496 // Check if display is initialized in AM.
20497 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20498 // Call might come when display is not yet added or has already been removed.
20499 if (DEBUG_CONFIGURATION) {
20500 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20506 if (values == null && mWindowManager != null) {
20507 // sentinel: fetch the current configuration from the window manager
20508 values = mWindowManager.computeNewConfiguration(displayId);
20511 if (mWindowManager != null) {
20512 // Update OOM levels based on display size.
20513 mProcessList.applyDisplaySize(mWindowManager);
20516 final long origId = Binder.clearCallingIdentity();
20518 if (values != null) {
20519 Settings.System.clearConfiguration(values);
20521 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20522 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20523 return mTmpUpdateConfigurationResult.changes != 0;
20525 Binder.restoreCallingIdentity(origId);
20530 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20531 boolean deferResume, int displayId) {
20532 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20533 displayId, null /* result */);
20537 * Updates override configuration specific for the selected display. If no config is provided,
20538 * new one will be computed in WM based on current display info.
20540 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20541 ActivityRecord starting, boolean deferResume, int displayId,
20542 UpdateConfigurationResult result) {
20544 boolean kept = true;
20546 if (mWindowManager != null) {
20547 mWindowManager.deferSurfaceLayout();
20550 if (values != null) {
20551 if (displayId == DEFAULT_DISPLAY) {
20552 // Override configuration of the default display duplicates global config, so
20553 // we're calling global config update instead for default display. It will also
20554 // apply the correct override config.
20555 changes = updateGlobalConfiguration(values, false /* initLocale */,
20556 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20558 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20562 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20564 if (mWindowManager != null) {
20565 mWindowManager.continueSurfaceLayout();
20569 if (result != null) {
20570 result.changes = changes;
20571 result.activityRelaunched = !kept;
20576 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20578 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20579 final int changes = mTempConfig.updateFrom(values);
20580 if (changes != 0) {
20581 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20582 + mTempConfig + " for displayId=" + displayId);
20583 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20585 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20586 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20587 // Reset the unsupported display size dialog.
20588 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20590 killAllBackgroundProcessesExcept(N,
20591 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20595 // Update the configuration with WM first and check if any of the stacks need to be resized
20596 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20597 // necessary. This way we don't need to relaunch again afterwards in
20598 // ensureActivityConfigurationLocked().
20599 if (mWindowManager != null) {
20600 final int[] resizedStacks =
20601 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20602 if (resizedStacks != null) {
20603 for (int stackId : resizedStacks) {
20604 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20612 /** Applies latest configuration and/or visibility updates if needed. */
20613 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20614 boolean kept = true;
20615 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20616 // mainStack is null during startup.
20617 if (mainStack != null) {
20618 if (changes != 0 && starting == null) {
20619 // If the configuration changed, and the caller is not already
20620 // in the process of starting an activity, then find the top
20621 // activity to check if its configuration needs to change.
20622 starting = mainStack.topRunningActivityLocked();
20625 if (starting != null) {
20626 kept = starting.ensureActivityConfigurationLocked(changes,
20627 false /* preserveWindow */);
20628 // And we need to make sure at this point that all other activities
20629 // are made visible with the correct configuration.
20630 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20631 !PRESERVE_WINDOWS);
20638 /** Helper method that requests bounds from WM and applies them to stack. */
20639 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20640 final Rect newStackBounds = new Rect();
20641 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20642 mStackSupervisor.resizeStackLocked(
20643 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20644 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20645 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20649 * Decide based on the configuration whether we should show the ANR,
20650 * crash, etc dialogs. The idea is that if there is no affordance to
20651 * press the on-screen buttons, or the user experience would be more
20652 * greatly impacted than the crash itself, we shouldn't show the dialog.
20654 * A thought: SystemUI might also want to get told about this, the Power
20655 * dialog / global actions also might want different behaviors.
20657 private static boolean shouldShowDialogs(Configuration config) {
20658 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20659 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20660 && config.navigation == Configuration.NAVIGATION_NONAV);
20661 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20662 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20663 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20664 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20665 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20666 return inputMethodExists && uiModeSupportsDialogs;
20670 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20671 synchronized (this) {
20672 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20673 if (srec != null) {
20674 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20680 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20681 Intent resultData) {
20683 synchronized (this) {
20684 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20686 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20692 public int getLaunchedFromUid(IBinder activityToken) {
20693 ActivityRecord srec;
20694 synchronized (this) {
20695 srec = ActivityRecord.forTokenLocked(activityToken);
20697 if (srec == null) {
20700 return srec.launchedFromUid;
20703 public String getLaunchedFromPackage(IBinder activityToken) {
20704 ActivityRecord srec;
20705 synchronized (this) {
20706 srec = ActivityRecord.forTokenLocked(activityToken);
20708 if (srec == null) {
20711 return srec.launchedFromPackage;
20714 // =========================================================
20715 // LIFETIME MANAGEMENT
20716 // =========================================================
20718 // Returns whether the app is receiving broadcast.
20719 // If receiving, fetch all broadcast queues which the app is
20720 // the current [or imminent] receiver on.
20721 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20722 ArraySet<BroadcastQueue> receivingQueues) {
20723 if (!app.curReceivers.isEmpty()) {
20724 for (BroadcastRecord r : app.curReceivers) {
20725 receivingQueues.add(r.queue);
20730 // It's not the current receiver, but it might be starting up to become one
20731 for (BroadcastQueue queue : mBroadcastQueues) {
20732 final BroadcastRecord r = queue.mPendingBroadcast;
20733 if (r != null && r.curApp == app) {
20734 // found it; report which queue it's in
20735 receivingQueues.add(queue);
20739 return !receivingQueues.isEmpty();
20742 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20743 int targetUid, ComponentName targetComponent, String targetProcess) {
20744 if (!mTrackingAssociations) {
20747 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20748 = mAssociations.get(targetUid);
20749 if (components == null) {
20750 components = new ArrayMap<>();
20751 mAssociations.put(targetUid, components);
20753 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20754 if (sourceUids == null) {
20755 sourceUids = new SparseArray<>();
20756 components.put(targetComponent, sourceUids);
20758 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20759 if (sourceProcesses == null) {
20760 sourceProcesses = new ArrayMap<>();
20761 sourceUids.put(sourceUid, sourceProcesses);
20763 Association ass = sourceProcesses.get(sourceProcess);
20765 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20767 sourceProcesses.put(sourceProcess, ass);
20771 if (ass.mNesting == 1) {
20772 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20773 ass.mLastState = sourceState;
20778 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20779 ComponentName targetComponent) {
20780 if (!mTrackingAssociations) {
20783 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20784 = mAssociations.get(targetUid);
20785 if (components == null) {
20788 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20789 if (sourceUids == null) {
20792 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20793 if (sourceProcesses == null) {
20796 Association ass = sourceProcesses.get(sourceProcess);
20797 if (ass == null || ass.mNesting <= 0) {
20801 if (ass.mNesting == 0) {
20802 long uptime = SystemClock.uptimeMillis();
20803 ass.mTime += uptime - ass.mStartTime;
20804 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20805 += uptime - ass.mLastStateUptime;
20806 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20810 private void noteUidProcessState(final int uid, final int state) {
20811 mBatteryStatsService.noteUidProcessState(uid, state);
20812 if (mTrackingAssociations) {
20813 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20814 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20815 = mAssociations.valueAt(i1);
20816 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20817 SparseArray<ArrayMap<String, Association>> sourceUids
20818 = targetComponents.valueAt(i2);
20819 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20820 if (sourceProcesses != null) {
20821 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20822 Association ass = sourceProcesses.valueAt(i4);
20823 if (ass.mNesting >= 1) {
20824 // currently associated
20825 long uptime = SystemClock.uptimeMillis();
20826 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20827 += uptime - ass.mLastStateUptime;
20828 ass.mLastState = state;
20829 ass.mLastStateUptime = uptime;
20838 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20839 boolean doingAll, long now) {
20840 if (mAdjSeq == app.adjSeq) {
20841 // This adjustment has already been computed.
20842 return app.curRawAdj;
20845 if (app.thread == null) {
20846 app.adjSeq = mAdjSeq;
20847 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20848 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20849 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20852 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20853 app.adjSource = null;
20854 app.adjTarget = null;
20856 app.cached = false;
20858 final int activitiesSize = app.activities.size();
20860 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20861 // The max adjustment doesn't allow this app to be anything
20862 // below foreground, so it is not worth doing work for it.
20863 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20864 app.adjType = "fixed";
20865 app.adjSeq = mAdjSeq;
20866 app.curRawAdj = app.maxAdj;
20867 app.foregroundActivities = false;
20868 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20869 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20870 // System processes can do UI, and when they do we want to have
20871 // them trim their memory after the user leaves the UI. To
20872 // facilitate this, here we need to determine whether or not it
20873 // is currently showing UI.
20874 app.systemNoUi = true;
20875 if (app == TOP_APP) {
20876 app.systemNoUi = false;
20877 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20878 app.adjType = "pers-top-activity";
20879 } else if (app.hasTopUi) {
20880 app.systemNoUi = false;
20881 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20882 app.adjType = "pers-top-ui";
20883 } else if (activitiesSize > 0) {
20884 for (int j = 0; j < activitiesSize; j++) {
20885 final ActivityRecord r = app.activities.get(j);
20887 app.systemNoUi = false;
20891 if (!app.systemNoUi) {
20892 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20894 return (app.curAdj=app.maxAdj);
20897 app.systemNoUi = false;
20899 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20901 // Determine the importance of the process, starting with most
20902 // important to least, and assign an appropriate OOM adjustment.
20906 boolean foregroundActivities = false;
20907 mTmpBroadcastQueue.clear();
20908 if (app == TOP_APP) {
20909 // The last app on the list is the foreground app.
20910 adj = ProcessList.FOREGROUND_APP_ADJ;
20911 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20912 app.adjType = "top-activity";
20913 foregroundActivities = true;
20914 procState = PROCESS_STATE_CUR_TOP;
20915 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20916 } else if (app.instr != null) {
20917 // Don't want to kill running instrumentation.
20918 adj = ProcessList.FOREGROUND_APP_ADJ;
20919 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20920 app.adjType = "instrumentation";
20921 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20922 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20923 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20924 // An app that is currently receiving a broadcast also
20925 // counts as being in the foreground for OOM killer purposes.
20926 // It's placed in a sched group based on the nature of the
20927 // broadcast as reflected by which queue it's active in.
20928 adj = ProcessList.FOREGROUND_APP_ADJ;
20929 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20930 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20931 app.adjType = "broadcast";
20932 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20933 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20934 } else if (app.executingServices.size() > 0) {
20935 // An app that is currently executing a service callback also
20936 // counts as being in the foreground.
20937 adj = ProcessList.FOREGROUND_APP_ADJ;
20938 schedGroup = app.execServicesFg ?
20939 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20940 app.adjType = "exec-service";
20941 procState = ActivityManager.PROCESS_STATE_SERVICE;
20942 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20943 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20945 // As far as we know the process is empty. We may change our mind later.
20946 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20947 // At this point we don't actually know the adjustment. Use the cached adj
20948 // value that the caller wants us to.
20950 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20953 app.adjType = "cch-empty";
20954 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20957 // Examine all activities if not already foreground.
20958 if (!foregroundActivities && activitiesSize > 0) {
20959 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20960 for (int j = 0; j < activitiesSize; j++) {
20961 final ActivityRecord r = app.activities.get(j);
20962 if (r.app != app) {
20963 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20964 + " instead of expected " + app);
20965 if (r.app == null || (r.app.uid == app.uid)) {
20966 // Only fix things up when they look sane
20973 // App has a visible activity; only upgrade adjustment.
20974 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20975 adj = ProcessList.VISIBLE_APP_ADJ;
20976 app.adjType = "vis-activity";
20977 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20979 if (procState > PROCESS_STATE_CUR_TOP) {
20980 procState = PROCESS_STATE_CUR_TOP;
20981 app.adjType = "vis-activity";
20982 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20984 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20985 app.cached = false;
20987 foregroundActivities = true;
20988 final TaskRecord task = r.getTask();
20989 if (task != null && minLayer > 0) {
20990 final int layer = task.mLayerRank;
20991 if (layer >= 0 && minLayer > layer) {
20996 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20997 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20998 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20999 app.adjType = "pause-activity";
21000 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21002 if (procState > PROCESS_STATE_CUR_TOP) {
21003 procState = PROCESS_STATE_CUR_TOP;
21004 app.adjType = "pause-activity";
21005 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21007 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21008 app.cached = false;
21010 foregroundActivities = true;
21011 } else if (r.state == ActivityState.STOPPING) {
21012 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21013 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21014 app.adjType = "stop-activity";
21015 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21017 // For the process state, we will at this point consider the
21018 // process to be cached. It will be cached either as an activity
21019 // or empty depending on whether the activity is finishing. We do
21020 // this so that we can treat the process as cached for purposes of
21021 // memory trimming (determing current memory level, trim command to
21022 // send to process) since there can be an arbitrary number of stopping
21023 // processes and they should soon all go into the cached state.
21024 if (!r.finishing) {
21025 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21026 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21027 app.adjType = "stop-activity";
21028 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21031 app.cached = false;
21033 foregroundActivities = true;
21035 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21036 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21037 app.adjType = "cch-act";
21038 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21042 if (adj == ProcessList.VISIBLE_APP_ADJ) {
21047 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21048 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21049 if (app.foregroundServices) {
21050 // The user is aware of this app, so make it visible.
21051 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21052 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21053 app.cached = false;
21054 app.adjType = "fg-service";
21055 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21056 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21057 } else if (app.hasOverlayUi) {
21058 // The process is display an overlay UI.
21059 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21060 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21061 app.cached = false;
21062 app.adjType = "has-overlay-ui";
21063 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21064 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21068 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21069 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21070 if (app.forcingToImportant != null) {
21071 // This is currently used for toasts... they are not interactive, and
21072 // we don't want them to cause the app to become fully foreground (and
21073 // thus out of background check), so we yes the best background level we can.
21074 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21075 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21076 app.cached = false;
21077 app.adjType = "force-imp";
21078 app.adjSource = app.forcingToImportant;
21079 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21080 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21084 if (app == mHeavyWeightProcess) {
21085 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21086 // We don't want to kill the current heavy-weight process.
21087 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21088 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21089 app.cached = false;
21090 app.adjType = "heavy";
21091 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21093 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21094 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21095 app.adjType = "heavy";
21096 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21100 if (app == mHomeProcess) {
21101 if (adj > ProcessList.HOME_APP_ADJ) {
21102 // This process is hosting what we currently consider to be the
21103 // home app, so we don't want to let it go into the background.
21104 adj = ProcessList.HOME_APP_ADJ;
21105 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21106 app.cached = false;
21107 app.adjType = "home";
21108 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21110 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21111 procState = ActivityManager.PROCESS_STATE_HOME;
21112 app.adjType = "home";
21113 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21117 if (app == mPreviousProcess && app.activities.size() > 0) {
21118 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21119 // This was the previous process that showed UI to the user.
21120 // We want to try to keep it around more aggressively, to give
21121 // a good experience around switching between two apps.
21122 adj = ProcessList.PREVIOUS_APP_ADJ;
21123 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21124 app.cached = false;
21125 app.adjType = "previous";
21126 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21128 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21129 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21130 app.adjType = "previous";
21131 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21135 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21136 + " reason=" + app.adjType);
21138 // By default, we use the computed adjustment. It may be changed if
21139 // there are applications dependent on our services or providers, but
21140 // this gives us a baseline and makes sure we don't get into an
21141 // infinite recursion.
21142 app.adjSeq = mAdjSeq;
21143 app.curRawAdj = adj;
21144 app.hasStartedServices = false;
21146 if (mBackupTarget != null && app == mBackupTarget.app) {
21147 // If possible we want to avoid killing apps while they're being backed up
21148 if (adj > ProcessList.BACKUP_APP_ADJ) {
21149 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21150 adj = ProcessList.BACKUP_APP_ADJ;
21151 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21152 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21154 app.adjType = "backup";
21155 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21156 app.cached = false;
21158 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21159 procState = ActivityManager.PROCESS_STATE_BACKUP;
21160 app.adjType = "backup";
21161 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21165 boolean mayBeTop = false;
21166 String mayBeTopType = null;
21167 Object mayBeTopSource = null;
21168 Object mayBeTopTarget = null;
21170 for (int is = app.services.size()-1;
21171 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21172 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21173 || procState > ActivityManager.PROCESS_STATE_TOP);
21175 ServiceRecord s = app.services.valueAt(is);
21176 if (s.startRequested) {
21177 app.hasStartedServices = true;
21178 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21179 procState = ActivityManager.PROCESS_STATE_SERVICE;
21180 app.adjType = "started-services";
21181 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21183 if (app.hasShownUi && app != mHomeProcess) {
21184 // If this process has shown some UI, let it immediately
21185 // go to the LRU list because it may be pretty heavy with
21186 // UI stuff. We'll tag it with a label just to help
21187 // debug and understand what is going on.
21188 if (adj > ProcessList.SERVICE_ADJ) {
21189 app.adjType = "cch-started-ui-services";
21192 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21193 // This service has seen some activity within
21194 // recent memory, so we will keep its process ahead
21195 // of the background processes.
21196 if (adj > ProcessList.SERVICE_ADJ) {
21197 adj = ProcessList.SERVICE_ADJ;
21198 app.adjType = "started-services";
21199 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21200 app.cached = false;
21203 // If we have let the service slide into the background
21204 // state, still have some text describing what it is doing
21205 // even though the service no longer has an impact.
21206 if (adj > ProcessList.SERVICE_ADJ) {
21207 app.adjType = "cch-started-services";
21212 for (int conni = s.connections.size()-1;
21213 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21214 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21215 || procState > ActivityManager.PROCESS_STATE_TOP);
21217 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21219 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21220 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21221 || procState > ActivityManager.PROCESS_STATE_TOP);
21223 // XXX should compute this based on the max of
21224 // all connected clients.
21225 ConnectionRecord cr = clist.get(i);
21226 if (cr.binding.client == app) {
21227 // Binding to ourself is not interesting.
21231 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21232 ProcessRecord client = cr.binding.client;
21233 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21234 TOP_APP, doingAll, now);
21235 int clientProcState = client.curProcState;
21236 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21237 // If the other app is cached for any reason, for purposes here
21238 // we are going to consider it empty. The specific cached state
21239 // doesn't propagate except under certain conditions.
21240 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21242 String adjType = null;
21243 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21244 // Not doing bind OOM management, so treat
21245 // this guy more like a started service.
21246 if (app.hasShownUi && app != mHomeProcess) {
21247 // If this process has shown some UI, let it immediately
21248 // go to the LRU list because it may be pretty heavy with
21249 // UI stuff. We'll tag it with a label just to help
21250 // debug and understand what is going on.
21251 if (adj > clientAdj) {
21252 adjType = "cch-bound-ui-services";
21254 app.cached = false;
21256 clientProcState = procState;
21258 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21259 // This service has not seen activity within
21260 // recent memory, so allow it to drop to the
21261 // LRU list if there is no other reason to keep
21262 // it around. We'll also tag it with a label just
21263 // to help debug and undertand what is going on.
21264 if (adj > clientAdj) {
21265 adjType = "cch-bound-services";
21271 if (adj > clientAdj) {
21272 // If this process has recently shown UI, and
21273 // the process that is binding to it is less
21274 // important than being visible, then we don't
21275 // care about the binding as much as we care
21276 // about letting this process get into the LRU
21277 // list to be killed and restarted if needed for
21279 if (app.hasShownUi && app != mHomeProcess
21280 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21281 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21282 adjType = "cch-bound-ui-services";
21286 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21287 |Context.BIND_IMPORTANT)) != 0) {
21288 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21289 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21290 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21291 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21292 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21293 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21294 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21295 newAdj = clientAdj;
21297 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21298 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21303 if (!client.cached) {
21304 app.cached = false;
21306 if (adj > newAdj) {
21308 adjType = "service";
21312 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21313 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21314 // This will treat important bound services identically to
21315 // the top app, which may behave differently than generic
21316 // foreground work.
21317 if (client.curSchedGroup > schedGroup) {
21318 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21319 schedGroup = client.curSchedGroup;
21321 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21324 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21325 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21326 // Special handling of clients who are in the top state.
21327 // We *may* want to consider this process to be in the
21328 // top state as well, but only if there is not another
21329 // reason for it to be running. Being on the top is a
21330 // special state, meaning you are specifically running
21331 // for the current top app. If the process is already
21332 // running in the background for some other reason, it
21333 // is more important to continue considering it to be
21334 // in the background state.
21336 mayBeTopType = "service";
21337 mayBeTopSource = cr.binding.client;
21338 mayBeTopTarget = s.name;
21339 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21341 // Special handling for above-top states (persistent
21342 // processes). These should not bring the current process
21343 // into the top state, since they are not on top. Instead
21344 // give them the best state after that.
21345 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21347 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21348 } else if (mWakefulness
21349 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21350 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21353 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21356 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21360 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21361 if (clientProcState <
21362 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21364 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21367 if (clientProcState <
21368 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21370 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21373 if (procState > clientProcState) {
21374 procState = clientProcState;
21375 if (adjType == null) {
21376 adjType = "service";
21379 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21380 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21381 app.pendingUiClean = true;
21383 if (adjType != null) {
21384 app.adjType = adjType;
21385 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21386 .REASON_SERVICE_IN_USE;
21387 app.adjSource = cr.binding.client;
21388 app.adjSourceProcState = clientProcState;
21389 app.adjTarget = s.name;
21390 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21391 + ": " + app + ", due to " + cr.binding.client
21392 + " adj=" + adj + " procState=" + procState);
21395 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21396 app.treatLikeActivity = true;
21398 final ActivityRecord a = cr.activity;
21399 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21400 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21401 (a.visible || a.state == ActivityState.RESUMED ||
21402 a.state == ActivityState.PAUSING)) {
21403 adj = ProcessList.FOREGROUND_APP_ADJ;
21404 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21405 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21406 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21408 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21411 app.cached = false;
21412 app.adjType = "service";
21413 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21414 .REASON_SERVICE_IN_USE;
21416 app.adjSourceProcState = procState;
21417 app.adjTarget = s.name;
21418 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21426 for (int provi = app.pubProviders.size()-1;
21427 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21428 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21429 || procState > ActivityManager.PROCESS_STATE_TOP);
21431 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21432 for (int i = cpr.connections.size()-1;
21433 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21434 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21435 || procState > ActivityManager.PROCESS_STATE_TOP);
21437 ContentProviderConnection conn = cpr.connections.get(i);
21438 ProcessRecord client = conn.client;
21439 if (client == app) {
21440 // Being our own client is not interesting.
21443 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21444 int clientProcState = client.curProcState;
21445 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21446 // If the other app is cached for any reason, for purposes here
21447 // we are going to consider it empty.
21448 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21450 String adjType = null;
21451 if (adj > clientAdj) {
21452 if (app.hasShownUi && app != mHomeProcess
21453 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21454 adjType = "cch-ui-provider";
21456 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21457 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21458 adjType = "provider";
21460 app.cached &= client.cached;
21462 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21463 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21464 // Special handling of clients who are in the top state.
21465 // We *may* want to consider this process to be in the
21466 // top state as well, but only if there is not another
21467 // reason for it to be running. Being on the top is a
21468 // special state, meaning you are specifically running
21469 // for the current top app. If the process is already
21470 // running in the background for some other reason, it
21471 // is more important to continue considering it to be
21472 // in the background state.
21474 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21475 mayBeTopType = adjType = "provider-top";
21476 mayBeTopSource = client;
21477 mayBeTopTarget = cpr.name;
21479 // Special handling for above-top states (persistent
21480 // processes). These should not bring the current process
21481 // into the top state, since they are not on top. Instead
21482 // give them the best state after that.
21484 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21485 if (adjType == null) {
21486 adjType = "provider";
21490 if (procState > clientProcState) {
21491 procState = clientProcState;
21493 if (client.curSchedGroup > schedGroup) {
21494 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21496 if (adjType != null) {
21497 app.adjType = adjType;
21498 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21499 .REASON_PROVIDER_IN_USE;
21500 app.adjSource = client;
21501 app.adjSourceProcState = clientProcState;
21502 app.adjTarget = cpr.name;
21503 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21504 + ": " + app + ", due to " + client
21505 + " adj=" + adj + " procState=" + procState);
21508 // If the provider has external (non-framework) process
21509 // dependencies, ensure that its adjustment is at least
21510 // FOREGROUND_APP_ADJ.
21511 if (cpr.hasExternalProcessHandles()) {
21512 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21513 adj = ProcessList.FOREGROUND_APP_ADJ;
21514 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21515 app.cached = false;
21516 app.adjType = "ext-provider";
21517 app.adjTarget = cpr.name;
21518 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21520 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21521 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21526 if (app.lastProviderTime > 0 &&
21527 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21528 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21529 adj = ProcessList.PREVIOUS_APP_ADJ;
21530 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21531 app.cached = false;
21532 app.adjType = "recent-provider";
21533 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21535 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21536 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21537 app.adjType = "recent-provider";
21538 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21542 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21543 // A client of one of our services or providers is in the top state. We
21544 // *may* want to be in the top state, but not if we are already running in
21545 // the background for some other reason. For the decision here, we are going
21546 // to pick out a few specific states that we want to remain in when a client
21547 // is top (states that tend to be longer-term) and otherwise allow it to go
21548 // to the top state.
21549 switch (procState) {
21550 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21551 // Something else is keeping it at this level, just leave it.
21553 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21554 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21555 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21556 case ActivityManager.PROCESS_STATE_SERVICE:
21557 // These all are longer-term states, so pull them up to the top
21558 // of the background states, but not all the way to the top state.
21559 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21560 app.adjType = mayBeTopType;
21561 app.adjSource = mayBeTopSource;
21562 app.adjTarget = mayBeTopTarget;
21563 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21564 + ": " + app + ", due to " + mayBeTopSource
21565 + " adj=" + adj + " procState=" + procState);
21568 // Otherwise, top is a better choice, so take it.
21569 procState = ActivityManager.PROCESS_STATE_TOP;
21570 app.adjType = mayBeTopType;
21571 app.adjSource = mayBeTopSource;
21572 app.adjTarget = mayBeTopTarget;
21573 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21574 + ": " + app + ", due to " + mayBeTopSource
21575 + " adj=" + adj + " procState=" + procState);
21580 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21581 if (app.hasClientActivities) {
21582 // This is a cached process, but with client activities. Mark it so.
21583 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21584 app.adjType = "cch-client-act";
21585 } else if (app.treatLikeActivity) {
21586 // This is a cached process, but somebody wants us to treat it like it has
21587 // an activity, okay!
21588 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21589 app.adjType = "cch-as-act";
21593 if (adj == ProcessList.SERVICE_ADJ) {
21595 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21596 mNewNumServiceProcs++;
21597 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21598 if (!app.serviceb) {
21599 // This service isn't far enough down on the LRU list to
21600 // normally be a B service, but if we are low on RAM and it
21601 // is large we want to force it down since we would prefer to
21602 // keep launcher over it.
21603 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21604 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21605 app.serviceHighRam = true;
21606 app.serviceb = true;
21607 //Slog.i(TAG, "ADJ " + app + " high ram!");
21609 mNewNumAServiceProcs++;
21610 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21613 app.serviceHighRam = false;
21616 if (app.serviceb) {
21617 adj = ProcessList.SERVICE_B_ADJ;
21621 app.curRawAdj = adj;
21623 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21624 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21625 if (adj > app.maxAdj) {
21627 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21628 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21632 // Do final modification to adj. Everything we do between here and applying
21633 // the final setAdj must be done in this function, because we will also use
21634 // it when computing the final cached adj later. Note that we don't need to
21635 // worry about this for max adj above, since max adj will always be used to
21636 // keep it out of the cached vaues.
21637 app.curAdj = app.modifyRawOomAdj(adj);
21638 app.curSchedGroup = schedGroup;
21639 app.curProcState = procState;
21640 app.foregroundActivities = foregroundActivities;
21642 return app.curRawAdj;
21646 * Record new PSS sample for a process.
21648 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21650 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21652 proc.lastPssTime = now;
21653 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21654 if (DEBUG_PSS) Slog.d(TAG_PSS,
21655 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21656 + " state=" + ProcessList.makeProcStateString(procState));
21657 if (proc.initialIdlePss == 0) {
21658 proc.initialIdlePss = pss;
21660 proc.lastPss = pss;
21661 proc.lastSwapPss = swapPss;
21662 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21663 proc.lastCachedPss = pss;
21664 proc.lastCachedSwapPss = swapPss;
21667 final SparseArray<Pair<Long, String>> watchUids
21668 = mMemWatchProcesses.getMap().get(proc.processName);
21670 if (watchUids != null) {
21671 Pair<Long, String> val = watchUids.get(proc.uid);
21673 val = watchUids.get(0);
21679 if (check != null) {
21680 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21681 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21682 if (!isDebuggable) {
21683 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21684 isDebuggable = true;
21687 if (isDebuggable) {
21688 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21689 final ProcessRecord myProc = proc;
21690 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21691 mMemWatchDumpProcName = proc.processName;
21692 mMemWatchDumpFile = heapdumpFile.toString();
21693 mMemWatchDumpPid = proc.pid;
21694 mMemWatchDumpUid = proc.uid;
21695 BackgroundThread.getHandler().post(new Runnable() {
21697 public void run() {
21698 revokeUriPermission(ActivityThread.currentActivityThread()
21699 .getApplicationThread(),
21700 null, DumpHeapActivity.JAVA_URI,
21701 Intent.FLAG_GRANT_READ_URI_PERMISSION
21702 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21703 UserHandle.myUserId());
21704 ParcelFileDescriptor fd = null;
21706 heapdumpFile.delete();
21707 fd = ParcelFileDescriptor.open(heapdumpFile,
21708 ParcelFileDescriptor.MODE_CREATE |
21709 ParcelFileDescriptor.MODE_TRUNCATE |
21710 ParcelFileDescriptor.MODE_WRITE_ONLY |
21711 ParcelFileDescriptor.MODE_APPEND);
21712 IApplicationThread thread = myProc.thread;
21713 if (thread != null) {
21715 if (DEBUG_PSS) Slog.d(TAG_PSS,
21716 "Requesting dump heap from "
21717 + myProc + " to " + heapdumpFile);
21718 thread.dumpHeap(/* managed= */ true,
21719 /* mallocInfo= */ false, /* runGc= */ false,
21720 heapdumpFile.toString(), fd);
21721 } catch (RemoteException e) {
21724 } catch (FileNotFoundException e) {
21725 e.printStackTrace();
21730 } catch (IOException e) {
21737 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21738 + ", but debugging not enabled");
21745 * Schedule PSS collection of a process.
21747 void requestPssLocked(ProcessRecord proc, int procState) {
21748 if (mPendingPssProcesses.contains(proc)) {
21751 if (mPendingPssProcesses.size() == 0) {
21752 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21754 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21755 proc.pssProcState = procState;
21756 mPendingPssProcesses.add(proc);
21760 * Schedule PSS collection of all processes.
21762 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21764 if (now < (mLastFullPssTime +
21765 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21766 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21770 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21771 mLastFullPssTime = now;
21772 mFullPssPending = true;
21773 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21774 mPendingPssProcesses.clear();
21775 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21776 ProcessRecord app = mLruProcesses.get(i);
21777 if (app.thread == null
21778 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21781 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21782 app.pssProcState = app.setProcState;
21783 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21784 mTestPssMode, isSleepingLocked(), now);
21785 mPendingPssProcesses.add(app);
21788 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21791 public void setTestPssMode(boolean enabled) {
21792 synchronized (this) {
21793 mTestPssMode = enabled;
21795 // Whenever we enable the mode, we want to take a snapshot all of current
21796 // process mem use.
21797 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21803 * Ask a given process to GC right now.
21805 final void performAppGcLocked(ProcessRecord app) {
21807 app.lastRequestedGc = SystemClock.uptimeMillis();
21808 if (app.thread != null) {
21809 if (app.reportLowMemory) {
21810 app.reportLowMemory = false;
21811 app.thread.scheduleLowMemory();
21813 app.thread.processInBackground();
21816 } catch (Exception e) {
21822 * Returns true if things are idle enough to perform GCs.
21824 private final boolean canGcNowLocked() {
21825 boolean processingBroadcasts = false;
21826 for (BroadcastQueue q : mBroadcastQueues) {
21827 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21828 processingBroadcasts = true;
21831 return !processingBroadcasts
21832 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21836 * Perform GCs on all processes that are waiting for it, but only
21837 * if things are idle.
21839 final void performAppGcsLocked() {
21840 final int N = mProcessesToGc.size();
21844 if (canGcNowLocked()) {
21845 while (mProcessesToGc.size() > 0) {
21846 ProcessRecord proc = mProcessesToGc.remove(0);
21847 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21848 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21849 <= SystemClock.uptimeMillis()) {
21850 // To avoid spamming the system, we will GC processes one
21851 // at a time, waiting a few seconds between each.
21852 performAppGcLocked(proc);
21853 scheduleAppGcsLocked();
21856 // It hasn't been long enough since we last GCed this
21857 // process... put it in the list to wait for its time.
21858 addProcessToGcListLocked(proc);
21864 scheduleAppGcsLocked();
21869 * If all looks good, perform GCs on all processes waiting for them.
21871 final void performAppGcsIfAppropriateLocked() {
21872 if (canGcNowLocked()) {
21873 performAppGcsLocked();
21876 // Still not idle, wait some more.
21877 scheduleAppGcsLocked();
21881 * Schedule the execution of all pending app GCs.
21883 final void scheduleAppGcsLocked() {
21884 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21886 if (mProcessesToGc.size() > 0) {
21887 // Schedule a GC for the time to the next process.
21888 ProcessRecord proc = mProcessesToGc.get(0);
21889 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21891 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21892 long now = SystemClock.uptimeMillis();
21893 if (when < (now+mConstants.GC_TIMEOUT)) {
21894 when = now + mConstants.GC_TIMEOUT;
21896 mHandler.sendMessageAtTime(msg, when);
21901 * Add a process to the array of processes waiting to be GCed. Keeps the
21902 * list in sorted order by the last GC time. The process can't already be
21905 final void addProcessToGcListLocked(ProcessRecord proc) {
21906 boolean added = false;
21907 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21908 if (mProcessesToGc.get(i).lastRequestedGc <
21909 proc.lastRequestedGc) {
21911 mProcessesToGc.add(i+1, proc);
21916 mProcessesToGc.add(0, proc);
21921 * Set up to ask a process to GC itself. This will either do it
21922 * immediately, or put it on the list of processes to gc the next
21923 * time things are idle.
21925 final void scheduleAppGcLocked(ProcessRecord app) {
21926 long now = SystemClock.uptimeMillis();
21927 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21930 if (!mProcessesToGc.contains(app)) {
21931 addProcessToGcListLocked(app);
21932 scheduleAppGcsLocked();
21936 final void checkExcessivePowerUsageLocked() {
21937 updateCpuStatsNow();
21939 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21940 boolean doCpuKills = true;
21941 if (mLastPowerCheckUptime == 0) {
21942 doCpuKills = false;
21944 final long curUptime = SystemClock.uptimeMillis();
21945 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21946 mLastPowerCheckUptime = curUptime;
21947 int i = mLruProcesses.size();
21950 ProcessRecord app = mLruProcesses.get(i);
21951 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21952 if (app.lastCpuTime <= 0) {
21955 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21957 StringBuilder sb = new StringBuilder(128);
21958 sb.append("CPU for ");
21959 app.toShortString(sb);
21960 sb.append(": over ");
21961 TimeUtils.formatDuration(uptimeSince, sb);
21962 sb.append(" used ");
21963 TimeUtils.formatDuration(cputimeUsed, sb);
21965 sb.append((cputimeUsed*100)/uptimeSince);
21967 Slog.i(TAG_POWER, sb.toString());
21969 // If the process has used too much CPU over the last duration, the
21970 // user probably doesn't want this, so kill!
21971 if (doCpuKills && uptimeSince > 0) {
21972 // What is the limit for this process?
21974 long checkDur = curUptime - app.whenUnimportant;
21975 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21976 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21977 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21978 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21979 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21980 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21981 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21983 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21985 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21986 synchronized (stats) {
21987 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21988 uptimeSince, cputimeUsed);
21990 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21991 + " dur=" + checkDur + " limit=" + cpuLimit, true);
21992 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21995 app.lastCpuTime = app.curCpuTime;
22000 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22002 boolean success = true;
22004 if (app.curRawAdj != app.setRawAdj) {
22005 app.setRawAdj = app.curRawAdj;
22010 if (app.curAdj != app.setAdj) {
22011 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22012 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22013 String msg = "Set " + app.pid + " " + app.processName + " adj "
22014 + app.curAdj + ": " + app.adjType;
22015 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22017 app.setAdj = app.curAdj;
22018 app.verifiedAdj = ProcessList.INVALID_ADJ;
22021 if (app.setSchedGroup != app.curSchedGroup) {
22022 int oldSchedGroup = app.setSchedGroup;
22023 app.setSchedGroup = app.curSchedGroup;
22024 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22025 String msg = "Setting sched group of " + app.processName
22026 + " to " + app.curSchedGroup;
22027 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22029 if (app.waitingToKill != null && app.curReceivers.isEmpty()
22030 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22031 app.kill(app.waitingToKill, true);
22035 switch (app.curSchedGroup) {
22036 case ProcessList.SCHED_GROUP_BACKGROUND:
22037 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22039 case ProcessList.SCHED_GROUP_TOP_APP:
22040 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22041 processGroup = THREAD_GROUP_TOP_APP;
22044 processGroup = THREAD_GROUP_DEFAULT;
22047 long oldId = Binder.clearCallingIdentity();
22049 setProcessGroup(app.pid, processGroup);
22050 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22051 // do nothing if we already switched to RT
22052 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22053 mVrController.onTopProcChangedLocked(app);
22054 if (mUseFifoUiScheduling) {
22055 // Switch UI pipeline for app to SCHED_FIFO
22056 app.savedPriority = Process.getThreadPriority(app.pid);
22057 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22058 if (app.renderThreadTid != 0) {
22059 scheduleAsFifoPriority(app.renderThreadTid,
22060 /* suppressLogs */true);
22061 if (DEBUG_OOM_ADJ) {
22062 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22063 app.renderThreadTid + ") to FIFO");
22066 if (DEBUG_OOM_ADJ) {
22067 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22071 // Boost priority for top app UI and render threads
22072 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22073 if (app.renderThreadTid != 0) {
22075 setThreadPriority(app.renderThreadTid,
22076 TOP_APP_PRIORITY_BOOST);
22077 } catch (IllegalArgumentException e) {
22078 // thread died, ignore
22083 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22084 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22085 mVrController.onTopProcChangedLocked(app);
22086 if (mUseFifoUiScheduling) {
22088 // Reset UI pipeline to SCHED_OTHER
22089 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22090 setThreadPriority(app.pid, app.savedPriority);
22091 if (app.renderThreadTid != 0) {
22092 setThreadScheduler(app.renderThreadTid,
22094 setThreadPriority(app.renderThreadTid, -4);
22096 } catch (IllegalArgumentException e) {
22098 "Failed to set scheduling policy, thread does not exist:\n"
22100 } catch (SecurityException e) {
22101 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22104 // Reset priority for top app UI and render threads
22105 setThreadPriority(app.pid, 0);
22106 if (app.renderThreadTid != 0) {
22107 setThreadPriority(app.renderThreadTid, 0);
22111 } catch (Exception e) {
22113 Slog.w(TAG, "Failed setting process group of " + app.pid
22114 + " to " + app.curSchedGroup);
22115 Slog.w(TAG, "at location", e);
22118 Binder.restoreCallingIdentity(oldId);
22122 if (app.repForegroundActivities != app.foregroundActivities) {
22123 app.repForegroundActivities = app.foregroundActivities;
22124 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22126 if (app.repProcState != app.curProcState) {
22127 app.repProcState = app.curProcState;
22128 if (app.thread != null) {
22131 //RuntimeException h = new RuntimeException("here");
22132 Slog.i(TAG, "Sending new process state " + app.repProcState
22133 + " to " + app /*, h*/);
22135 app.thread.setProcessState(app.repProcState);
22136 } catch (RemoteException e) {
22140 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22141 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22142 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22143 // Experimental code to more aggressively collect pss while
22144 // running test... the problem is that this tends to collect
22145 // the data right when a process is transitioning between process
22146 // states, which well tend to give noisy data.
22147 long start = SystemClock.uptimeMillis();
22148 long pss = Debug.getPss(app.pid, mTmpLong, null);
22149 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22150 mPendingPssProcesses.remove(app);
22151 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22152 + " to " + app.curProcState + ": "
22153 + (SystemClock.uptimeMillis()-start) + "ms");
22155 app.lastStateTime = now;
22156 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22157 mTestPssMode, isSleepingLocked(), now);
22158 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22159 + ProcessList.makeProcStateString(app.setProcState) + " to "
22160 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22161 + (app.nextPssTime-now) + ": " + app);
22163 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22164 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22166 requestPssLocked(app, app.setProcState);
22167 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22168 mTestPssMode, isSleepingLocked(), now);
22169 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22170 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22172 if (app.setProcState != app.curProcState) {
22173 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22174 String msg = "Proc state change of " + app.processName
22175 + " to " + app.curProcState;
22176 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22178 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22179 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22180 if (setImportant && !curImportant) {
22181 // This app is no longer something we consider important enough to allow to
22182 // use arbitrary amounts of battery power. Note
22183 // its current CPU time to later know to kill it if
22184 // it is not behaving well.
22185 app.whenUnimportant = now;
22186 app.lastCpuTime = 0;
22188 // Inform UsageStats of important process state change
22189 // Must be called before updating setProcState
22190 maybeUpdateUsageStatsLocked(app, nowElapsed);
22192 app.setProcState = app.curProcState;
22193 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22194 app.notCachedSinceIdle = false;
22197 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22199 app.procStateChanged = true;
22201 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22202 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22203 // For apps that sit around for a long time in the interactive state, we need
22204 // to report this at least once a day so they don't go idle.
22205 maybeUpdateUsageStatsLocked(app, nowElapsed);
22208 if (changes != 0) {
22209 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22210 "Changes in " + app + ": " + changes);
22211 int i = mPendingProcessChanges.size()-1;
22212 ProcessChangeItem item = null;
22214 item = mPendingProcessChanges.get(i);
22215 if (item.pid == app.pid) {
22216 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22217 "Re-using existing item: " + item);
22223 // No existing item in pending changes; need a new one.
22224 final int NA = mAvailProcessChanges.size();
22226 item = mAvailProcessChanges.remove(NA-1);
22227 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22228 "Retrieving available item: " + item);
22230 item = new ProcessChangeItem();
22231 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22232 "Allocating new item: " + item);
22235 item.pid = app.pid;
22236 item.uid = app.info.uid;
22237 if (mPendingProcessChanges.size() == 0) {
22238 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22239 "*** Enqueueing dispatch processes changed!");
22240 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22242 mPendingProcessChanges.add(item);
22244 item.changes |= changes;
22245 item.foregroundActivities = app.repForegroundActivities;
22246 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22247 "Item " + Integer.toHexString(System.identityHashCode(item))
22248 + " " + app.toShortString() + ": changes=" + item.changes
22249 + " foreground=" + item.foregroundActivities
22250 + " type=" + app.adjType + " source=" + app.adjSource
22251 + " target=" + app.adjTarget);
22257 private boolean isEphemeralLocked(int uid) {
22258 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22259 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22262 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22267 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22268 final UidRecord.ChangeItem pendingChange;
22269 if (uidRec == null || uidRec.pendingChange == null) {
22270 if (mPendingUidChanges.size() == 0) {
22271 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22272 "*** Enqueueing dispatch uid changed!");
22273 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22275 final int NA = mAvailUidChanges.size();
22277 pendingChange = mAvailUidChanges.remove(NA-1);
22278 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22279 "Retrieving available item: " + pendingChange);
22281 pendingChange = new UidRecord.ChangeItem();
22282 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22283 "Allocating new item: " + pendingChange);
22285 if (uidRec != null) {
22286 uidRec.pendingChange = pendingChange;
22287 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22288 // If this uid is going away, and we haven't yet reported it is gone,
22290 change |= UidRecord.CHANGE_IDLE;
22292 } else if (uid < 0) {
22293 throw new IllegalArgumentException("No UidRecord or uid");
22295 pendingChange.uidRecord = uidRec;
22296 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22297 mPendingUidChanges.add(pendingChange);
22299 pendingChange = uidRec.pendingChange;
22300 // If there is no change in idle or active state, then keep whatever was pending.
22301 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22302 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22303 | UidRecord.CHANGE_ACTIVE));
22305 // If there is no change in cached or uncached state, then keep whatever was pending.
22306 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22307 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22308 | UidRecord.CHANGE_UNCACHED));
22310 // If this is a report of the UID being gone, then we shouldn't keep any previous
22311 // report of it being active or cached. (That is, a gone uid is never active,
22312 // and never cached.)
22313 if ((change & UidRecord.CHANGE_GONE) != 0) {
22314 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22315 if (!uidRec.idle) {
22316 // If this uid is going away, and we haven't yet reported it is gone,
22318 change |= UidRecord.CHANGE_IDLE;
22322 pendingChange.change = change;
22323 pendingChange.processState = uidRec != null
22324 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22325 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22326 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22327 if (uidRec != null) {
22328 uidRec.lastReportedChange = change;
22329 uidRec.updateLastDispatchedProcStateSeq(change);
22332 // Directly update the power manager, since we sit on top of it and it is critical
22333 // it be kept in sync (so wake locks will be held as soon as appropriate).
22334 if (mLocalPowerManager != null) {
22335 // TO DO: dispatch cached/uncached changes here, so we don't need to report
22336 // all proc state changes.
22337 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22338 mLocalPowerManager.uidActive(pendingChange.uid);
22340 if ((change & UidRecord.CHANGE_IDLE) != 0) {
22341 mLocalPowerManager.uidIdle(pendingChange.uid);
22343 if ((change & UidRecord.CHANGE_GONE) != 0) {
22344 mLocalPowerManager.uidGone(pendingChange.uid);
22346 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22347 pendingChange.processState);
22352 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22353 String authority) {
22354 if (app == null) return;
22355 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22356 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22357 if (userState == null) return;
22358 final long now = SystemClock.elapsedRealtime();
22359 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22360 if (lastReported == null || lastReported < now - 60 * 1000L) {
22361 if (mSystemReady) {
22362 // Cannot touch the user stats if not system ready
22363 mUsageStatsService.reportContentProviderUsage(
22364 authority, providerPkgName, app.userId);
22366 userState.mProviderLastReportedFg.put(authority, now);
22371 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22372 if (DEBUG_USAGE_STATS) {
22373 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22374 + "] state changes: old = " + app.setProcState + ", new = "
22375 + app.curProcState);
22377 if (mUsageStatsService == null) {
22380 boolean isInteraction;
22381 // To avoid some abuse patterns, we are going to be careful about what we consider
22382 // to be an app interaction. Being the top activity doesn't count while the display
22383 // is sleeping, nor do short foreground services.
22384 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22385 isInteraction = true;
22386 app.fgInteractionTime = 0;
22387 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22388 if (app.fgInteractionTime == 0) {
22389 app.fgInteractionTime = nowElapsed;
22390 isInteraction = false;
22392 isInteraction = nowElapsed > app.fgInteractionTime
22393 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22396 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22397 app.fgInteractionTime = 0;
22399 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22400 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22401 app.interactionEventTime = nowElapsed;
22402 String[] packages = app.getPackageList();
22403 if (packages != null) {
22404 for (int i = 0; i < packages.length; i++) {
22405 mUsageStatsService.reportEvent(packages[i], app.userId,
22406 UsageEvents.Event.SYSTEM_INTERACTION);
22410 app.reportedInteraction = isInteraction;
22411 if (!isInteraction) {
22412 app.interactionEventTime = 0;
22416 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22417 if (proc.thread != null) {
22418 if (proc.baseProcessTracker != null) {
22419 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22424 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22425 ProcessRecord TOP_APP, boolean doingAll, long now) {
22426 if (app.thread == null) {
22430 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22432 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22435 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22437 if (isForeground != proc.foregroundServices) {
22438 proc.foregroundServices = isForeground;
22439 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22441 if (isForeground) {
22442 if (curProcs == null) {
22443 curProcs = new ArrayList<ProcessRecord>();
22444 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22446 if (!curProcs.contains(proc)) {
22447 curProcs.add(proc);
22448 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22449 proc.info.packageName, proc.info.uid);
22452 if (curProcs != null) {
22453 if (curProcs.remove(proc)) {
22454 mBatteryStatsService.noteEvent(
22455 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22456 proc.info.packageName, proc.info.uid);
22457 if (curProcs.size() <= 0) {
22458 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22464 updateOomAdjLocked();
22469 private final ActivityRecord resumedAppLocked() {
22470 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22474 pkg = act.packageName;
22475 uid = act.info.applicationInfo.uid;
22480 // Has the UID or resumed package name changed?
22481 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22482 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22483 if (mCurResumedPackage != null) {
22484 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22485 mCurResumedPackage, mCurResumedUid);
22487 mCurResumedPackage = pkg;
22488 mCurResumedUid = uid;
22489 if (mCurResumedPackage != null) {
22490 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22491 mCurResumedPackage, mCurResumedUid);
22498 * Update OomAdj for a specific process.
22499 * @param app The process to update
22500 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22501 * if necessary, or skip.
22502 * @return whether updateOomAdjLocked(app) was successful.
22504 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22505 final ActivityRecord TOP_ACT = resumedAppLocked();
22506 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22507 final boolean wasCached = app.cached;
22511 // This is the desired cached adjusment we want to tell it to use.
22512 // If our app is currently cached, we know it, and that is it. Otherwise,
22513 // we don't know it yet, and it needs to now be cached we will then
22514 // need to do a complete oom adj.
22515 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22516 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22517 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22518 SystemClock.uptimeMillis());
22520 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22521 // Changed to/from cached state, so apps after it in the LRU
22522 // list may also be changed.
22523 updateOomAdjLocked();
22528 final void updateOomAdjLocked() {
22529 final ActivityRecord TOP_ACT = resumedAppLocked();
22530 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22531 final long now = SystemClock.uptimeMillis();
22532 final long nowElapsed = SystemClock.elapsedRealtime();
22533 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22534 final int N = mLruProcesses.size();
22537 RuntimeException e = new RuntimeException();
22538 e.fillInStackTrace();
22539 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22542 // Reset state in all uid records.
22543 for (int i=mActiveUids.size()-1; i>=0; i--) {
22544 final UidRecord uidRec = mActiveUids.valueAt(i);
22545 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22546 "Starting update of " + uidRec);
22550 mStackSupervisor.rankTaskLayersIfNeeded();
22553 mNewNumServiceProcs = 0;
22554 mNewNumAServiceProcs = 0;
22556 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22557 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22559 // Let's determine how many processes we have running vs.
22560 // how many slots we have for background processes; we may want
22561 // to put multiple processes in a slot of there are enough of
22563 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22564 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22565 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22566 if (numEmptyProcs > cachedProcessLimit) {
22567 // If there are more empty processes than our limit on cached
22568 // processes, then use the cached process limit for the factor.
22569 // This ensures that the really old empty processes get pushed
22570 // down to the bottom, so if we are running low on memory we will
22571 // have a better chance at keeping around more cached processes
22572 // instead of a gazillion empty processes.
22573 numEmptyProcs = cachedProcessLimit;
22575 int emptyFactor = numEmptyProcs/numSlots;
22576 if (emptyFactor < 1) emptyFactor = 1;
22577 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22578 if (cachedFactor < 1) cachedFactor = 1;
22579 int stepCached = 0;
22583 int numTrimming = 0;
22585 mNumNonCachedProcs = 0;
22586 mNumCachedHiddenProcs = 0;
22588 // First update the OOM adjustment for each of the
22589 // application processes based on their current state.
22590 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22591 int nextCachedAdj = curCachedAdj+1;
22592 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22593 int nextEmptyAdj = curEmptyAdj+2;
22594 for (int i=N-1; i>=0; i--) {
22595 ProcessRecord app = mLruProcesses.get(i);
22596 if (!app.killedByAm && app.thread != null) {
22597 app.procStateChanged = false;
22598 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22600 // If we haven't yet assigned the final cached adj
22601 // to the process, do that now.
22602 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22603 switch (app.curProcState) {
22604 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22605 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22606 // This process is a cached process holding activities...
22607 // assign it the next cached value for that type, and then
22608 // step that cached level.
22609 app.curRawAdj = curCachedAdj;
22610 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22611 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22612 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22614 if (curCachedAdj != nextCachedAdj) {
22616 if (stepCached >= cachedFactor) {
22618 curCachedAdj = nextCachedAdj;
22619 nextCachedAdj += 2;
22620 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22621 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22627 // For everything else, assign next empty cached process
22628 // level and bump that up. Note that this means that
22629 // long-running services that have dropped down to the
22630 // cached level will be treated as empty (since their process
22631 // state is still as a service), which is what we want.
22632 app.curRawAdj = curEmptyAdj;
22633 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22634 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22635 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22637 if (curEmptyAdj != nextEmptyAdj) {
22639 if (stepEmpty >= emptyFactor) {
22641 curEmptyAdj = nextEmptyAdj;
22643 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22644 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22652 applyOomAdjLocked(app, true, now, nowElapsed);
22654 // Count the number of process types.
22655 switch (app.curProcState) {
22656 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22657 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22658 mNumCachedHiddenProcs++;
22660 if (numCached > cachedProcessLimit) {
22661 app.kill("cached #" + numCached, true);
22664 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22665 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22666 && app.lastActivityTime < oldTime) {
22667 app.kill("empty for "
22668 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22669 / 1000) + "s", true);
22672 if (numEmpty > emptyProcessLimit) {
22673 app.kill("empty #" + numEmpty, true);
22678 mNumNonCachedProcs++;
22682 if (app.isolated && app.services.size() <= 0) {
22683 // If this is an isolated process, and there are no
22684 // services running in it, then the process is no longer
22685 // needed. We agressively kill these because we can by
22686 // definition not re-use the same process again, and it is
22687 // good to avoid having whatever code was running in them
22688 // left sitting around after no longer needed.
22689 app.kill("isolated not needed", true);
22691 // Keeping this process, update its uid.
22692 final UidRecord uidRec = app.uidRecord;
22693 if (uidRec != null) {
22694 uidRec.ephemeral = app.info.isInstantApp();
22695 if (uidRec.curProcState > app.curProcState) {
22696 uidRec.curProcState = app.curProcState;
22698 if (app.foregroundServices) {
22699 uidRec.foregroundServices = true;
22704 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22705 && !app.killedByAm) {
22711 incrementProcStateSeqAndNotifyAppsLocked();
22713 mNumServiceProcs = mNewNumServiceProcs;
22715 // Now determine the memory trimming level of background processes.
22716 // Unfortunately we need to start at the back of the list to do this
22717 // properly. We only do this if the number of background apps we
22718 // are managing to keep around is less than half the maximum we desire;
22719 // if we are keeping a good number around, we'll let them use whatever
22720 // memory they want.
22721 final int numCachedAndEmpty = numCached + numEmpty;
22723 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22724 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22725 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22726 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22727 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22728 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22730 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22733 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22735 // We always allow the memory level to go up (better). We only allow it to go
22736 // down if we are in a state where that is allowed, *and* the total number of processes
22737 // has gone down since last time.
22738 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22739 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22740 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22741 if (memFactor > mLastMemoryLevel) {
22742 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22743 memFactor = mLastMemoryLevel;
22744 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22747 if (memFactor != mLastMemoryLevel) {
22748 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22750 mLastMemoryLevel = memFactor;
22751 mLastNumProcesses = mLruProcesses.size();
22752 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22753 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22754 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22755 if (mLowRamStartTime == 0) {
22756 mLowRamStartTime = now;
22760 switch (memFactor) {
22761 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22762 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22764 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22765 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22768 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22771 int factor = numTrimming/3;
22773 if (mHomeProcess != null) minFactor++;
22774 if (mPreviousProcess != null) minFactor++;
22775 if (factor < minFactor) factor = minFactor;
22776 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22777 for (int i=N-1; i>=0; i--) {
22778 ProcessRecord app = mLruProcesses.get(i);
22779 if (allChanged || app.procStateChanged) {
22780 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22781 app.procStateChanged = false;
22783 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22784 && !app.killedByAm) {
22785 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22787 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22788 "Trimming memory of " + app.processName + " to " + curLevel);
22789 app.thread.scheduleTrimMemory(curLevel);
22790 } catch (RemoteException e) {
22793 // For now we won't do this; our memory trimming seems
22794 // to be good enough at this point that destroying
22795 // activities causes more harm than good.
22796 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22797 && app != mHomeProcess && app != mPreviousProcess) {
22798 // Need to do this on its own message because the stack may not
22799 // be in a consistent state at this point.
22800 // For these apps we will also finish their activities
22801 // to help them free memory.
22802 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22806 app.trimMemoryLevel = curLevel;
22808 if (step >= factor) {
22810 switch (curLevel) {
22811 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22812 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22814 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22815 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22819 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22820 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22821 && app.thread != null) {
22823 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22824 "Trimming memory of heavy-weight " + app.processName
22825 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22826 app.thread.scheduleTrimMemory(
22827 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22828 } catch (RemoteException e) {
22831 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22833 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22834 || app.systemNoUi) && app.pendingUiClean) {
22835 // If this application is now in the background and it
22836 // had done UI, then give it the special trim level to
22837 // have it free UI resources.
22838 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22839 if (app.trimMemoryLevel < level && app.thread != null) {
22841 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22842 "Trimming memory of bg-ui " + app.processName
22844 app.thread.scheduleTrimMemory(level);
22845 } catch (RemoteException e) {
22848 app.pendingUiClean = false;
22850 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22852 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22853 "Trimming memory of fg " + app.processName
22854 + " to " + fgTrimLevel);
22855 app.thread.scheduleTrimMemory(fgTrimLevel);
22856 } catch (RemoteException e) {
22859 app.trimMemoryLevel = fgTrimLevel;
22863 if (mLowRamStartTime != 0) {
22864 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22865 mLowRamStartTime = 0;
22867 for (int i=N-1; i>=0; i--) {
22868 ProcessRecord app = mLruProcesses.get(i);
22869 if (allChanged || app.procStateChanged) {
22870 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22871 app.procStateChanged = false;
22873 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22874 || app.systemNoUi) && app.pendingUiClean) {
22875 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22876 && app.thread != null) {
22878 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22879 "Trimming memory of ui hidden " + app.processName
22880 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22881 app.thread.scheduleTrimMemory(
22882 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22883 } catch (RemoteException e) {
22886 app.pendingUiClean = false;
22888 app.trimMemoryLevel = 0;
22892 if (mAlwaysFinishActivities) {
22893 // Need to do this on its own message because the stack may not
22894 // be in a consistent state at this point.
22895 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22899 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22902 ArrayList<UidRecord> becameIdle = null;
22904 // Update from any uid changes.
22905 if (mLocalPowerManager != null) {
22906 mLocalPowerManager.startUidChanges();
22908 for (int i=mActiveUids.size()-1; i>=0; i--) {
22909 final UidRecord uidRec = mActiveUids.valueAt(i);
22910 int uidChange = UidRecord.CHANGE_PROCSTATE;
22911 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22912 && (uidRec.setProcState != uidRec.curProcState
22913 || uidRec.setWhitelist != uidRec.curWhitelist)) {
22914 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22915 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22916 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22917 + " to " + uidRec.curWhitelist);
22918 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22919 && !uidRec.curWhitelist) {
22920 // UID is now in the background (and not on the temp whitelist). Was it
22921 // previously in the foreground (or on the temp whitelist)?
22922 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22923 || uidRec.setWhitelist) {
22924 uidRec.lastBackgroundTime = nowElapsed;
22925 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22926 // Note: the background settle time is in elapsed realtime, while
22927 // the handler time base is uptime. All this means is that we may
22928 // stop background uids later than we had intended, but that only
22929 // happens because the device was sleeping so we are okay anyway.
22930 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22931 mConstants.BACKGROUND_SETTLE_TIME);
22934 if (uidRec.idle && !uidRec.setIdle) {
22935 uidChange = UidRecord.CHANGE_IDLE;
22936 if (becameIdle == null) {
22937 becameIdle = new ArrayList<>();
22939 becameIdle.add(uidRec);
22943 uidChange = UidRecord.CHANGE_ACTIVE;
22944 EventLogTags.writeAmUidActive(uidRec.uid);
22945 uidRec.idle = false;
22947 uidRec.lastBackgroundTime = 0;
22949 final boolean wasCached = uidRec.setProcState
22950 > ActivityManager.PROCESS_STATE_RECEIVER;
22951 final boolean isCached = uidRec.curProcState
22952 > ActivityManager.PROCESS_STATE_RECEIVER;
22953 if (wasCached != isCached ||
22954 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22955 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22957 uidRec.setProcState = uidRec.curProcState;
22958 uidRec.setWhitelist = uidRec.curWhitelist;
22959 uidRec.setIdle = uidRec.idle;
22960 enqueueUidChangeLocked(uidRec, -1, uidChange);
22961 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22962 if (uidRec.foregroundServices) {
22963 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22967 if (mLocalPowerManager != null) {
22968 mLocalPowerManager.finishUidChanges();
22971 if (becameIdle != null) {
22972 // If we have any new uids that became idle this time, we need to make sure
22973 // they aren't left with running services.
22974 for (int i = becameIdle.size() - 1; i >= 0; i--) {
22975 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22979 if (mProcessStats.shouldWriteNowLocked(now)) {
22980 mHandler.post(new Runnable() {
22981 @Override public void run() {
22982 synchronized (ActivityManagerService.this) {
22983 mProcessStats.writeStateAsyncLocked();
22989 if (DEBUG_OOM_ADJ) {
22990 final long duration = SystemClock.uptimeMillis() - now;
22992 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22993 new RuntimeException("here").fillInStackTrace());
22995 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23001 public void makePackageIdle(String packageName, int userId) {
23002 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23003 != PackageManager.PERMISSION_GRANTED) {
23004 String msg = "Permission Denial: makePackageIdle() from pid="
23005 + Binder.getCallingPid()
23006 + ", uid=" + Binder.getCallingUid()
23007 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23009 throw new SecurityException(msg);
23011 final int callingPid = Binder.getCallingPid();
23012 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23013 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23014 long callingId = Binder.clearCallingIdentity();
23015 synchronized(this) {
23017 IPackageManager pm = AppGlobals.getPackageManager();
23020 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23021 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23022 } catch (RemoteException e) {
23024 if (pkgUid == -1) {
23025 throw new IllegalArgumentException("Unknown package name " + packageName);
23028 if (mLocalPowerManager != null) {
23029 mLocalPowerManager.startUidChanges();
23031 final int appId = UserHandle.getAppId(pkgUid);
23032 final int N = mActiveUids.size();
23033 for (int i=N-1; i>=0; i--) {
23034 final UidRecord uidRec = mActiveUids.valueAt(i);
23035 final long bgTime = uidRec.lastBackgroundTime;
23036 if (bgTime > 0 && !uidRec.idle) {
23037 if (UserHandle.getAppId(uidRec.uid) == appId) {
23038 if (userId == UserHandle.USER_ALL ||
23039 userId == UserHandle.getUserId(uidRec.uid)) {
23040 EventLogTags.writeAmUidIdle(uidRec.uid);
23041 uidRec.idle = true;
23042 uidRec.setIdle = true;
23043 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23044 + " from package " + packageName + " user " + userId);
23045 doStopUidLocked(uidRec.uid, uidRec);
23051 if (mLocalPowerManager != null) {
23052 mLocalPowerManager.finishUidChanges();
23054 Binder.restoreCallingIdentity(callingId);
23059 final void idleUids() {
23060 synchronized (this) {
23061 final int N = mActiveUids.size();
23065 final long nowElapsed = SystemClock.elapsedRealtime();
23066 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23068 if (mLocalPowerManager != null) {
23069 mLocalPowerManager.startUidChanges();
23071 for (int i=N-1; i>=0; i--) {
23072 final UidRecord uidRec = mActiveUids.valueAt(i);
23073 final long bgTime = uidRec.lastBackgroundTime;
23074 if (bgTime > 0 && !uidRec.idle) {
23075 if (bgTime <= maxBgTime) {
23076 EventLogTags.writeAmUidIdle(uidRec.uid);
23077 uidRec.idle = true;
23078 uidRec.setIdle = true;
23079 doStopUidLocked(uidRec.uid, uidRec);
23081 if (nextTime == 0 || nextTime > bgTime) {
23087 if (mLocalPowerManager != null) {
23088 mLocalPowerManager.finishUidChanges();
23090 if (nextTime > 0) {
23091 mHandler.removeMessages(IDLE_UIDS_MSG);
23092 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23093 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23099 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23100 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23101 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23105 void incrementProcStateSeqAndNotifyAppsLocked() {
23106 if (mWaitForNetworkTimeoutMs <= 0) {
23109 // Used for identifying which uids need to block for network.
23110 ArrayList<Integer> blockingUids = null;
23111 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23112 final UidRecord uidRec = mActiveUids.valueAt(i);
23113 // If the network is not restricted for uid, then nothing to do here.
23114 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23117 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23120 // If process state is not changed, then there's nothing to do.
23121 if (uidRec.setProcState == uidRec.curProcState) {
23124 final int blockState = getBlockStateForUid(uidRec);
23125 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23126 // there's nothing the app needs to do in this scenario.
23127 if (blockState == NETWORK_STATE_NO_CHANGE) {
23130 synchronized (uidRec.networkStateLock) {
23131 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23132 if (blockState == NETWORK_STATE_BLOCK) {
23133 if (blockingUids == null) {
23134 blockingUids = new ArrayList<>();
23136 blockingUids.add(uidRec.uid);
23138 if (DEBUG_NETWORK) {
23139 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23140 + " threads for uid: " + uidRec);
23142 if (uidRec.waitingForNetwork) {
23143 uidRec.networkStateLock.notifyAll();
23149 // There are no uids that need to block, so nothing more to do.
23150 if (blockingUids == null) {
23154 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23155 final ProcessRecord app = mLruProcesses.get(i);
23156 if (!blockingUids.contains(app.uid)) {
23159 if (!app.killedByAm && app.thread != null) {
23160 final UidRecord uidRec = mActiveUids.get(app.uid);
23162 if (DEBUG_NETWORK) {
23163 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23166 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23167 } catch (RemoteException ignored) {
23174 * Checks if the uid is coming from background to foreground or vice versa and returns
23175 * appropriate block state based on this.
23177 * @return blockState based on whether the uid is coming from background to foreground or
23178 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23179 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23180 * {@link #NETWORK_STATE_NO_CHANGE}.
23183 int getBlockStateForUid(UidRecord uidRec) {
23184 // Denotes whether uid's process state is currently allowed network access.
23185 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23186 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23187 // Denotes whether uid's process state was previously allowed network access.
23188 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23189 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23191 // When the uid is coming to foreground, AMS should inform the app thread that it should
23192 // block for the network rules to get updated before launching an activity.
23193 if (!wasAllowed && isAllowed) {
23194 return NETWORK_STATE_BLOCK;
23196 // When the uid is going to background, AMS should inform the app thread that if an
23197 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23198 if (wasAllowed && !isAllowed) {
23199 return NETWORK_STATE_UNBLOCK;
23201 return NETWORK_STATE_NO_CHANGE;
23204 final void runInBackgroundDisabled(int uid) {
23205 synchronized (this) {
23206 UidRecord uidRec = mActiveUids.get(uid);
23207 if (uidRec != null) {
23208 // This uid is actually running... should it be considered background now?
23210 doStopUidLocked(uidRec.uid, uidRec);
23213 // This uid isn't actually running... still send a report about it being "stopped".
23214 doStopUidLocked(uid, null);
23219 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23220 mServices.stopInBackgroundLocked(uid);
23221 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23225 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23227 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23228 long duration, String tag) {
23229 if (DEBUG_WHITELISTS) {
23230 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23231 + targetUid + ", " + duration + ")");
23234 synchronized (mPidsSelfLocked) {
23235 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23237 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23241 if (!pr.whitelistManager) {
23242 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23243 != PackageManager.PERMISSION_GRANTED) {
23244 if (DEBUG_WHITELISTS) {
23245 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23246 + ": pid " + callerPid + " is not allowed");
23253 tempWhitelistUidLocked(targetUid, duration, tag);
23257 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23259 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23260 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23261 setUidTempWhitelistStateLocked(targetUid, true);
23262 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23265 void pushTempWhitelist() {
23267 final PendingTempWhitelist[] list;
23269 // First copy out the pending changes... we need to leave them in the map for now,
23270 // in case someone needs to check what is coming up while we don't have the lock held.
23271 synchronized(this) {
23272 N = mPendingTempWhitelist.size();
23273 list = new PendingTempWhitelist[N];
23274 for (int i = 0; i < N; i++) {
23275 list[i] = mPendingTempWhitelist.valueAt(i);
23279 // Now safely dispatch changes to device idle controller.
23280 for (int i = 0; i < N; i++) {
23281 PendingTempWhitelist ptw = list[i];
23282 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23283 ptw.duration, true, ptw.tag);
23286 // And now we can safely remove them from the map.
23287 synchronized(this) {
23288 for (int i = 0; i < N; i++) {
23289 PendingTempWhitelist ptw = list[i];
23290 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23291 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23292 mPendingTempWhitelist.removeAt(index);
23298 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23299 boolean changed = false;
23300 for (int i=mActiveUids.size()-1; i>=0; i--) {
23301 final UidRecord uidRec = mActiveUids.valueAt(i);
23302 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23303 uidRec.curWhitelist = onWhitelist;
23308 updateOomAdjLocked();
23312 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23313 boolean changed = false;
23314 final UidRecord uidRec = mActiveUids.get(uid);
23315 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23316 uidRec.curWhitelist = onWhitelist;
23317 updateOomAdjLocked();
23321 final void trimApplications() {
23322 synchronized (this) {
23325 // First remove any unused application processes whose package
23326 // has been removed.
23327 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23328 final ProcessRecord app = mRemovedProcesses.get(i);
23329 if (app.activities.size() == 0
23330 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23332 TAG, "Exiting empty application process "
23333 + app.toShortString() + " ("
23334 + (app.thread != null ? app.thread.asBinder() : null)
23336 if (app.pid > 0 && app.pid != MY_PID) {
23337 app.kill("empty", false);
23340 app.thread.scheduleExit();
23341 } catch (Exception e) {
23342 // Ignore exceptions.
23345 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23346 mRemovedProcesses.remove(i);
23348 if (app.persistent) {
23349 addAppLocked(app.info, null, false, null /* ABI override */);
23354 // Now update the oom adj for all processes.
23355 updateOomAdjLocked();
23359 /** This method sends the specified signal to each of the persistent apps */
23360 public void signalPersistentProcesses(int sig) throws RemoteException {
23361 if (sig != SIGNAL_USR1) {
23362 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23365 synchronized (this) {
23366 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23367 != PackageManager.PERMISSION_GRANTED) {
23368 throw new SecurityException("Requires permission "
23369 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23372 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23373 ProcessRecord r = mLruProcesses.get(i);
23374 if (r.thread != null && r.persistent) {
23375 sendSignal(r.pid, sig);
23381 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23382 if (proc == null || proc == mProfileProc) {
23383 proc = mProfileProc;
23384 profileType = mProfileType;
23385 clearProfilerLocked();
23387 if (proc == null) {
23391 proc.thread.profilerControl(false, null, profileType);
23392 } catch (RemoteException e) {
23393 throw new IllegalStateException("Process disappeared");
23397 private void clearProfilerLocked() {
23398 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23400 mProfilerInfo.profileFd.close();
23401 } catch (IOException e) {
23404 mProfileApp = null;
23405 mProfileProc = null;
23406 mProfilerInfo = null;
23409 public boolean profileControl(String process, int userId, boolean start,
23410 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23413 synchronized (this) {
23414 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23415 // its own permission.
23416 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23417 != PackageManager.PERMISSION_GRANTED) {
23418 throw new SecurityException("Requires permission "
23419 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23422 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23423 throw new IllegalArgumentException("null profile info or fd");
23426 ProcessRecord proc = null;
23427 if (process != null) {
23428 proc = findProcessLocked(process, userId, "profileControl");
23431 if (start && (proc == null || proc.thread == null)) {
23432 throw new IllegalArgumentException("Unknown process: " + process);
23436 stopProfilerLocked(null, 0);
23437 setProfileApp(proc.info, proc.processName, profilerInfo);
23438 mProfileProc = proc;
23439 mProfileType = profileType;
23440 ParcelFileDescriptor fd = profilerInfo.profileFd;
23443 } catch (IOException e) {
23446 profilerInfo.profileFd = fd;
23447 proc.thread.profilerControl(start, profilerInfo, profileType);
23450 mProfilerInfo.profileFd.close();
23451 } catch (IOException e) {
23453 mProfilerInfo.profileFd = null;
23455 stopProfilerLocked(proc, profileType);
23456 if (profilerInfo != null && profilerInfo.profileFd != null) {
23458 profilerInfo.profileFd.close();
23459 } catch (IOException e) {
23466 } catch (RemoteException e) {
23467 throw new IllegalStateException("Process disappeared");
23469 if (profilerInfo != null && profilerInfo.profileFd != null) {
23471 profilerInfo.profileFd.close();
23472 } catch (IOException e) {
23478 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23479 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23480 userId, true, ALLOW_FULL_ONLY, callName, null);
23481 ProcessRecord proc = null;
23483 int pid = Integer.parseInt(process);
23484 synchronized (mPidsSelfLocked) {
23485 proc = mPidsSelfLocked.get(pid);
23487 } catch (NumberFormatException e) {
23490 if (proc == null) {
23491 ArrayMap<String, SparseArray<ProcessRecord>> all
23492 = mProcessNames.getMap();
23493 SparseArray<ProcessRecord> procs = all.get(process);
23494 if (procs != null && procs.size() > 0) {
23495 proc = procs.valueAt(0);
23496 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23497 for (int i=1; i<procs.size(); i++) {
23498 ProcessRecord thisProc = procs.valueAt(i);
23499 if (thisProc.userId == userId) {
23511 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23512 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23515 synchronized (this) {
23516 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23517 // its own permission (same as profileControl).
23518 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23519 != PackageManager.PERMISSION_GRANTED) {
23520 throw new SecurityException("Requires permission "
23521 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23525 throw new IllegalArgumentException("null fd");
23528 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23529 if (proc == null || proc.thread == null) {
23530 throw new IllegalArgumentException("Unknown process: " + process);
23533 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23534 if (!isDebuggable) {
23535 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23536 throw new SecurityException("Process not debuggable: " + proc);
23540 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23544 } catch (RemoteException e) {
23545 throw new IllegalStateException("Process disappeared");
23550 } catch (IOException e) {
23557 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23558 String reportPackage) {
23559 if (processName != null) {
23560 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23561 "setDumpHeapDebugLimit()");
23563 synchronized (mPidsSelfLocked) {
23564 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23565 if (proc == null) {
23566 throw new SecurityException("No process found for calling pid "
23567 + Binder.getCallingPid());
23569 if (!Build.IS_DEBUGGABLE
23570 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23571 throw new SecurityException("Not running a debuggable build");
23573 processName = proc.processName;
23575 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23576 throw new SecurityException("Package " + reportPackage + " is not running in "
23581 synchronized (this) {
23582 if (maxMemSize > 0) {
23583 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23586 mMemWatchProcesses.remove(processName, uid);
23588 mMemWatchProcesses.getMap().remove(processName);
23595 public void dumpHeapFinished(String path) {
23596 synchronized (this) {
23597 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23598 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23599 + " does not match last pid " + mMemWatchDumpPid);
23602 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23603 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23604 + " does not match last path " + mMemWatchDumpFile);
23607 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23608 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23610 // Forced gc to clean up the remnant hprof fd.
23611 Runtime.getRuntime().gc();
23615 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23616 public void monitor() {
23617 synchronized (this) { }
23620 void onCoreSettingsChange(Bundle settings) {
23621 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23622 ProcessRecord processRecord = mLruProcesses.get(i);
23624 if (processRecord.thread != null) {
23625 processRecord.thread.setCoreSettings(settings);
23627 } catch (RemoteException re) {
23633 // Multi-user methods
23636 * Start user, if its not already running, but don't bring it to foreground.
23639 public boolean startUserInBackground(final int userId) {
23640 return mUserController.startUser(userId, /* foreground */ false);
23644 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23645 return mUserController.unlockUser(userId, token, secret, listener);
23649 public boolean switchUser(final int targetUserId) {
23650 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23652 UserInfo targetUserInfo;
23653 synchronized (this) {
23654 currentUserId = mUserController.getCurrentUserIdLocked();
23655 targetUserInfo = mUserController.getUserInfo(targetUserId);
23656 if (targetUserId == currentUserId) {
23657 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23660 if (targetUserInfo == null) {
23661 Slog.w(TAG, "No user info for user #" + targetUserId);
23664 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23665 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23666 + " when device is in demo mode");
23669 if (!targetUserInfo.supportsSwitchTo()) {
23670 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23673 if (targetUserInfo.isManagedProfile()) {
23674 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23677 mUserController.setTargetUserIdLocked(targetUserId);
23679 if (mUserController.mUserSwitchUiEnabled) {
23680 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23681 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23682 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23683 mUiHandler.sendMessage(mHandler.obtainMessage(
23684 START_USER_SWITCH_UI_MSG, userNames));
23686 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23687 mHandler.sendMessage(mHandler.obtainMessage(
23688 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23693 void scheduleStartProfilesLocked() {
23694 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23695 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23696 DateUtils.SECOND_IN_MILLIS);
23701 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23702 return mUserController.stopUser(userId, force, callback);
23706 public UserInfo getCurrentUser() {
23707 return mUserController.getCurrentUser();
23710 String getStartedUserState(int userId) {
23711 synchronized (this) {
23712 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23713 return UserState.stateToString(userState.state);
23718 public boolean isUserRunning(int userId, int flags) {
23719 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23720 && checkCallingPermission(INTERACT_ACROSS_USERS)
23721 != PackageManager.PERMISSION_GRANTED) {
23722 String msg = "Permission Denial: isUserRunning() from pid="
23723 + Binder.getCallingPid()
23724 + ", uid=" + Binder.getCallingUid()
23725 + " requires " + INTERACT_ACROSS_USERS;
23727 throw new SecurityException(msg);
23729 synchronized (this) {
23730 return mUserController.isUserRunningLocked(userId, flags);
23735 public int[] getRunningUserIds() {
23736 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23737 != PackageManager.PERMISSION_GRANTED) {
23738 String msg = "Permission Denial: isUserRunning() from pid="
23739 + Binder.getCallingPid()
23740 + ", uid=" + Binder.getCallingUid()
23741 + " requires " + INTERACT_ACROSS_USERS;
23743 throw new SecurityException(msg);
23745 synchronized (this) {
23746 return mUserController.getStartedUserArrayLocked();
23751 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23752 mUserController.registerUserSwitchObserver(observer, name);
23756 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23757 mUserController.unregisterUserSwitchObserver(observer);
23760 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23761 if (info == null) return null;
23762 ApplicationInfo newInfo = new ApplicationInfo(info);
23763 newInfo.initForUser(userId);
23767 public boolean isUserStopped(int userId) {
23768 synchronized (this) {
23769 return mUserController.getStartedUserStateLocked(userId) == null;
23773 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23775 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23779 ActivityInfo info = new ActivityInfo(aInfo);
23780 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23784 private boolean processSanityChecksLocked(ProcessRecord process) {
23785 if (process == null || process.thread == null) {
23789 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23790 if (!isDebuggable) {
23791 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23799 public boolean startBinderTracking() throws RemoteException {
23800 synchronized (this) {
23801 mBinderTransactionTrackingEnabled = true;
23802 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23803 // permission (same as profileControl).
23804 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23805 != PackageManager.PERMISSION_GRANTED) {
23806 throw new SecurityException("Requires permission "
23807 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23810 for (int i = 0; i < mLruProcesses.size(); i++) {
23811 ProcessRecord process = mLruProcesses.get(i);
23812 if (!processSanityChecksLocked(process)) {
23816 process.thread.startBinderTracking();
23817 } catch (RemoteException e) {
23818 Log.v(TAG, "Process disappared");
23825 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23827 synchronized (this) {
23828 mBinderTransactionTrackingEnabled = false;
23829 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23830 // permission (same as profileControl).
23831 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23832 != PackageManager.PERMISSION_GRANTED) {
23833 throw new SecurityException("Requires permission "
23834 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23838 throw new IllegalArgumentException("null fd");
23841 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23842 pw.println("Binder transaction traces for all processes.\n");
23843 for (ProcessRecord process : mLruProcesses) {
23844 if (!processSanityChecksLocked(process)) {
23848 pw.println("Traces for process: " + process.processName);
23851 TransferPipe tp = new TransferPipe();
23853 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23854 tp.go(fd.getFileDescriptor());
23858 } catch (IOException e) {
23859 pw.println("Failure while dumping IPC traces from " + process +
23860 ". Exception: " + e);
23862 } catch (RemoteException e) {
23863 pw.println("Got a RemoteException while dumping IPC traces from " +
23864 process + ". Exception: " + e);
23875 } catch (IOException e) {
23882 final class LocalService extends ActivityManagerInternal {
23884 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23885 int targetUserId) {
23886 synchronized (ActivityManagerService.this) {
23887 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23888 targetPkg, intent, null, targetUserId);
23893 public String checkContentProviderAccess(String authority, int userId) {
23894 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23898 public void onWakefulnessChanged(int wakefulness) {
23899 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23903 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23904 String processName, String abiOverride, int uid, Runnable crashHandler) {
23905 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23906 processName, abiOverride, uid, crashHandler);
23910 public SleepToken acquireSleepToken(String tag, int displayId) {
23911 Preconditions.checkNotNull(tag);
23912 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23916 public ComponentName getHomeActivityForUser(int userId) {
23917 synchronized (ActivityManagerService.this) {
23918 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23919 return homeActivity == null ? null : homeActivity.realActivity;
23924 public void onUserRemoved(int userId) {
23925 synchronized (ActivityManagerService.this) {
23926 ActivityManagerService.this.onUserStoppedLocked(userId);
23928 mBatteryStatsService.onUserRemoved(userId);
23932 public void onLocalVoiceInteractionStarted(IBinder activity,
23933 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23934 synchronized (ActivityManagerService.this) {
23935 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23936 voiceSession, voiceInteractor);
23941 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23942 synchronized (ActivityManagerService.this) {
23943 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23944 reasons, timestamp);
23949 public void notifyAppTransitionFinished() {
23950 synchronized (ActivityManagerService.this) {
23951 mStackSupervisor.notifyAppTransitionDone();
23956 public void notifyAppTransitionCancelled() {
23957 synchronized (ActivityManagerService.this) {
23958 mStackSupervisor.notifyAppTransitionDone();
23963 public List<IBinder> getTopVisibleActivities() {
23964 synchronized (ActivityManagerService.this) {
23965 return mStackSupervisor.getTopVisibleActivities();
23970 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23971 synchronized (ActivityManagerService.this) {
23972 mStackSupervisor.setDockedStackMinimized(minimized);
23977 public void killForegroundAppsForUser(int userHandle) {
23978 synchronized (ActivityManagerService.this) {
23979 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23980 final int NP = mProcessNames.getMap().size();
23981 for (int ip = 0; ip < NP; ip++) {
23982 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23983 final int NA = apps.size();
23984 for (int ia = 0; ia < NA; ia++) {
23985 final ProcessRecord app = apps.valueAt(ia);
23986 if (app.persistent) {
23987 // We don't kill persistent processes.
23992 } else if (app.userId == userHandle && app.foregroundActivities) {
23993 app.removed = true;
23999 final int N = procs.size();
24000 for (int i = 0; i < N; i++) {
24001 removeProcessLocked(procs.get(i), false, true, "kill all fg");
24007 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24009 if (!(target instanceof PendingIntentRecord)) {
24010 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24013 synchronized (ActivityManagerService.this) {
24014 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24019 public void setDeviceIdleWhitelist(int[] appids) {
24020 synchronized (ActivityManagerService.this) {
24021 mDeviceIdleWhitelist = appids;
24026 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24027 synchronized (ActivityManagerService.this) {
24028 mDeviceIdleTempWhitelist = appids;
24029 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24034 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24036 Preconditions.checkNotNull(values, "Configuration must not be null");
24037 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24038 synchronized (ActivityManagerService.this) {
24039 updateConfigurationLocked(values, null, false, true, userId,
24040 false /* deferResume */);
24045 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24047 Preconditions.checkNotNull(intents, "intents");
24048 final String[] resolvedTypes = new String[intents.length];
24049 for (int i = 0; i < intents.length; i++) {
24050 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24053 // UID of the package on user userId.
24054 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24055 // packageUid may not be initialized.
24056 int packageUid = 0;
24058 packageUid = AppGlobals.getPackageManager().getPackageUid(
24059 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24060 } catch (RemoteException e) {
24061 // Shouldn't happen.
24064 synchronized (ActivityManagerService.this) {
24065 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24066 /*resultTo*/ null, bOptions, userId);
24071 public int getUidProcessState(int uid) {
24072 return getUidState(uid);
24076 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24077 synchronized (ActivityManagerService.this) {
24079 // We might change the visibilities here, so prepare an empty app transition which
24080 // might be overridden later if we actually change visibilities.
24081 final boolean wasTransitionSet =
24082 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24083 if (!wasTransitionSet) {
24084 mWindowManager.prepareAppTransition(TRANSIT_NONE,
24085 false /* alwaysKeepCurrent */);
24087 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24089 // If there was a transition set already we don't want to interfere with it as we
24090 // might be starting it too early.
24091 if (!wasTransitionSet) {
24092 mWindowManager.executeAppTransition();
24095 if (callback != null) {
24101 public boolean isSystemReady() {
24102 // no need to synchronize(this) just to read & return the value
24103 return mSystemReady;
24107 public void notifyKeyguardTrustedChanged() {
24108 synchronized (ActivityManagerService.this) {
24109 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24110 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24116 * Sets if the given pid has an overlay UI or not.
24118 * @param pid The pid we are setting overlay UI for.
24119 * @param hasOverlayUi True if the process has overlay UI.
24120 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24123 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24124 synchronized (ActivityManagerService.this) {
24125 final ProcessRecord pr;
24126 synchronized (mPidsSelfLocked) {
24127 pr = mPidsSelfLocked.get(pid);
24129 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24133 if (pr.hasOverlayUi == hasOverlayUi) {
24136 pr.hasOverlayUi = hasOverlayUi;
24137 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24138 updateOomAdjLocked(pr, true);
24143 * Called after the network policy rules are updated by
24144 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24145 * and {@param procStateSeq}.
24148 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24149 if (DEBUG_NETWORK) {
24150 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24151 + uid + " seq: " + procStateSeq);
24154 synchronized (ActivityManagerService.this) {
24155 record = mActiveUids.get(uid);
24156 if (record == null) {
24157 if (DEBUG_NETWORK) {
24158 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24159 + " procStateSeq: " + procStateSeq);
24164 synchronized (record.networkStateLock) {
24165 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24166 if (DEBUG_NETWORK) {
24167 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24168 + " been handled for uid: " + uid);
24172 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24173 if (record.curProcStateSeq > procStateSeq) {
24174 if (DEBUG_NETWORK) {
24175 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24176 + ", curProcstateSeq: " + record.curProcStateSeq
24177 + ", procStateSeq: " + procStateSeq);
24181 if (record.waitingForNetwork) {
24182 if (DEBUG_NETWORK) {
24183 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24184 + ", procStateSeq: " + procStateSeq);
24186 record.networkStateLock.notifyAll();
24192 * Called after virtual display Id is updated by
24193 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24194 * {@param vrVr2dDisplayId}.
24197 public void setVr2dDisplayId(int vr2dDisplayId) {
24199 Slog.d(TAG, "setVr2dDisplayId called for: " +
24202 synchronized (ActivityManagerService.this) {
24203 mVr2dDisplayId = vr2dDisplayId;
24208 public void saveANRState(String reason) {
24209 synchronized (ActivityManagerService.this) {
24210 final StringWriter sw = new StringWriter();
24211 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24212 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24213 if (reason != null) {
24214 pw.println(" Reason: " + reason);
24217 mActivityStarter.dump(pw, " ", null);
24219 pw.println("-------------------------------------------------------------------------------");
24220 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24221 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24226 mLastANRState = sw.toString();
24231 public void clearSavedANRState() {
24232 synchronized (ActivityManagerService.this) {
24233 mLastANRState = null;
24238 public void setFocusedActivity(IBinder token) {
24239 synchronized (ActivityManagerService.this) {
24240 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24242 throw new IllegalArgumentException(
24243 "setFocusedActivity: No activity record matching token=" + token);
24245 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24246 r, "setFocusedActivity")) {
24247 mStackSupervisor.resumeFocusedStackTopActivityLocked();
24253 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24254 if (packageName == null) return false;
24256 synchronized (ActivityManagerService.this) {
24257 for (int i = 0; i < mLruProcesses.size(); i++) {
24258 final ProcessRecord processRecord = mLruProcesses.get(i);
24259 if (processRecord.uid == uid) {
24260 for (int j = 0; j < processRecord.activities.size(); j++) {
24261 final ActivityRecord activityRecord = processRecord.activities.get(j);
24262 if (packageName.equals(activityRecord.packageName)) {
24274 * Called by app main thread to wait for the network policy rules to get updated.
24276 * @param procStateSeq The sequence number indicating the process state change that the main
24277 * thread is interested in.
24280 public void waitForNetworkStateUpdate(long procStateSeq) {
24281 final int callingUid = Binder.getCallingUid();
24282 if (DEBUG_NETWORK) {
24283 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24286 synchronized (this) {
24287 record = mActiveUids.get(callingUid);
24288 if (record == null) {
24292 synchronized (record.networkStateLock) {
24293 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24294 if (DEBUG_NETWORK) {
24295 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24296 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24297 + " lastProcStateSeqDispatchedToObservers: "
24298 + record.lastDispatchedProcStateSeq);
24302 if (record.curProcStateSeq > procStateSeq) {
24303 if (DEBUG_NETWORK) {
24304 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24305 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24306 + ", procStateSeq: " + procStateSeq);
24310 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24311 if (DEBUG_NETWORK) {
24312 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24313 + procStateSeq + ", so no need to wait. Uid: "
24314 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24315 + record.lastNetworkUpdatedProcStateSeq);
24320 if (DEBUG_NETWORK) {
24321 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24322 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24324 final long startTime = SystemClock.uptimeMillis();
24325 record.waitingForNetwork = true;
24326 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24327 record.waitingForNetwork = false;
24328 final long totalTime = SystemClock.uptimeMillis() - startTime;
24329 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24330 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24331 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24332 + procStateSeq + " UidRec: " + record
24333 + " validateUidRec: " + mValidateUids.get(callingUid));
24335 } catch (InterruptedException e) {
24336 Thread.currentThread().interrupt();
24341 public void waitForBroadcastIdle(PrintWriter pw) {
24342 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24344 boolean idle = true;
24345 synchronized (this) {
24346 for (BroadcastQueue queue : mBroadcastQueues) {
24347 if (!queue.isIdle()) {
24348 final String msg = "Waiting for queue " + queue + " to become idle...";
24358 final String msg = "All broadcast queues are idle!";
24364 SystemClock.sleep(1000);
24370 * Return the user id of the last resumed activity.
24373 public @UserIdInt int getLastResumedActivityUserId() {
24374 enforceCallingPermission(
24375 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24376 synchronized (this) {
24377 if (mLastResumedActivity == null) {
24378 return mUserController.getCurrentUserIdLocked();
24380 return mLastResumedActivity.userId;
24385 * An implementation of IAppTask, that allows an app to manage its own tasks via
24386 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24387 * only the process that calls getAppTasks() can call the AppTask methods.
24389 class AppTaskImpl extends IAppTask.Stub {
24390 private int mTaskId;
24391 private int mCallingUid;
24393 public AppTaskImpl(int taskId, int callingUid) {
24395 mCallingUid = callingUid;
24398 private void checkCaller() {
24399 if (mCallingUid != Binder.getCallingUid()) {
24400 throw new SecurityException("Caller " + mCallingUid
24401 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24406 public void finishAndRemoveTask() {
24409 synchronized (ActivityManagerService.this) {
24410 long origId = Binder.clearCallingIdentity();
24412 // We remove the task from recents to preserve backwards
24413 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24414 REMOVE_FROM_RECENTS)) {
24415 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24418 Binder.restoreCallingIdentity(origId);
24424 public ActivityManager.RecentTaskInfo getTaskInfo() {
24427 synchronized (ActivityManagerService.this) {
24428 long origId = Binder.clearCallingIdentity();
24430 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24432 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24434 return createRecentTaskInfoFromTaskRecord(tr);
24436 Binder.restoreCallingIdentity(origId);
24442 public void moveToFront() {
24444 // Will bring task to front if it already has a root activity.
24445 final long origId = Binder.clearCallingIdentity();
24447 synchronized (this) {
24448 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24451 Binder.restoreCallingIdentity(origId);
24456 public int startActivity(IBinder whoThread, String callingPackage,
24457 Intent intent, String resolvedType, Bundle bOptions) {
24460 int callingUser = UserHandle.getCallingUserId();
24462 IApplicationThread appThread;
24463 synchronized (ActivityManagerService.this) {
24464 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24466 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24468 appThread = IApplicationThread.Stub.asInterface(whoThread);
24469 if (appThread == null) {
24470 throw new IllegalArgumentException("Bad app thread " + appThread);
24473 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24474 resolvedType, null, null, null, null, 0, 0, null, null,
24475 null, bOptions, false, callingUser, tr, "AppTaskImpl");
24479 public void setExcludeFromRecents(boolean exclude) {
24482 synchronized (ActivityManagerService.this) {
24483 long origId = Binder.clearCallingIdentity();
24485 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24487 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24489 Intent intent = tr.getBaseIntent();
24491 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24493 intent.setFlags(intent.getFlags()
24494 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24497 Binder.restoreCallingIdentity(origId);
24504 * Kill processes for the user with id userId and that depend on the package named packageName
24507 public void killPackageDependents(String packageName, int userId) {
24508 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24509 if (packageName == null) {
24510 throw new NullPointerException(
24511 "Cannot kill the dependents of a package without its name.");
24514 long callingId = Binder.clearCallingIdentity();
24515 IPackageManager pm = AppGlobals.getPackageManager();
24518 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24519 } catch (RemoteException e) {
24521 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24522 throw new IllegalArgumentException(
24523 "Cannot kill dependents of non-existing package " + packageName);
24526 synchronized(this) {
24527 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24528 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24529 "dep: " + packageName);
24532 Binder.restoreCallingIdentity(callingId);
24537 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24538 throws RemoteException {
24539 final long callingId = Binder.clearCallingIdentity();
24541 mKeyguardController.dismissKeyguard(token, callback);
24543 Binder.restoreCallingIdentity(callingId);
24548 public int restartUserInBackground(final int userId) {
24549 return mUserController.restartUser(userId, /* foreground */ false);
24553 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24554 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24555 "scheduleApplicationInfoChanged()");
24557 synchronized (this) {
24558 final long origId = Binder.clearCallingIdentity();
24560 updateApplicationInfoLocked(packageNames, userId);
24562 Binder.restoreCallingIdentity(origId);
24567 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24568 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24569 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24570 final ProcessRecord app = mLruProcesses.get(i);
24571 if (app.thread == null) {
24575 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24579 final int packageCount = app.pkgList.size();
24580 for (int j = 0; j < packageCount; j++) {
24581 final String packageName = app.pkgList.keyAt(j);
24582 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24584 final ApplicationInfo ai = AppGlobals.getPackageManager()
24585 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24587 app.thread.scheduleApplicationInfoChanged(ai);
24589 } catch (RemoteException e) {
24590 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24591 packageName, app));
24599 * Attach an agent to the specified process (proces name or PID)
24601 public void attachAgent(String process, String path) {
24603 synchronized (this) {
24604 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24605 if (proc == null || proc.thread == null) {
24606 throw new IllegalArgumentException("Unknown process: " + process);
24609 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24610 if (!isDebuggable) {
24611 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24612 throw new SecurityException("Process not debuggable: " + proc);
24616 proc.thread.attachAgent(path);
24618 } catch (RemoteException e) {
24619 throw new IllegalStateException("Process disappeared");
24624 public static class Injector {
24625 private NetworkManagementInternal mNmi;
24627 public Context getContext() {
24631 public AppOpsService getAppOpsService(File file, Handler handler) {
24632 return new AppOpsService(file, handler);
24635 public Handler getUiHandler(ActivityManagerService service) {
24636 return service.new UiHandler();
24639 public boolean isNetworkRestrictedForUid(int uid) {
24640 if (ensureHasNetworkManagementInternal()) {
24641 return mNmi.isNetworkRestrictedForUid(uid);
24646 private boolean ensureHasNetworkManagementInternal() {
24647 if (mNmi == null) {
24648 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24650 return mNmi != null;
24655 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24656 throws RemoteException {
24657 synchronized (this) {
24658 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24662 final long origId = Binder.clearCallingIdentity();
24664 r.setShowWhenLocked(showWhenLocked);
24666 Binder.restoreCallingIdentity(origId);
24672 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24673 synchronized (this) {
24674 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24678 final long origId = Binder.clearCallingIdentity();
24680 r.setTurnScreenOn(turnScreenOn);
24682 Binder.restoreCallingIdentity(origId);