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 // Figure out the value returned when access is allowed
8845 final int allowedResult;
8846 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8847 // If we're extending a persistable grant, then we need to return
8848 // "targetUid" so that we always create a grant data structure to
8849 // support take/release APIs
8850 allowedResult = targetUid;
8852 // Otherwise, we can return "-1" to indicate that no grant data
8853 // structures need to be created
8857 if (targetUid >= 0) {
8858 // First... does the target actually need this permission?
8859 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8860 // No need to grant the target this permission.
8861 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8862 "Target " + targetPkg + " already has full permission to " + grantUri);
8863 return allowedResult;
8866 // First... there is no target package, so can anyone access it?
8867 boolean allowed = pi.exported;
8868 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8869 if (pi.readPermission != null) {
8873 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8874 if (pi.writePermission != null) {
8879 return allowedResult;
8883 /* There is a special cross user grant if:
8884 * - The target is on another user.
8885 * - Apps on the current user can access the uri without any uid permissions.
8886 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8887 * grant uri permissions.
8889 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8890 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8891 modeFlags, false /*without considering the uid permissions*/);
8893 // Second... is the provider allowing granting of URI permissions?
8894 if (!specialCrossUserGrant) {
8895 if (!pi.grantUriPermissions) {
8896 throw new SecurityException("Provider " + pi.packageName
8898 + " does not allow granting of Uri permissions (uri "
8901 if (pi.uriPermissionPatterns != null) {
8902 final int N = pi.uriPermissionPatterns.length;
8903 boolean allowed = false;
8904 for (int i=0; i<N; i++) {
8905 if (pi.uriPermissionPatterns[i] != null
8906 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8912 throw new SecurityException("Provider " + pi.packageName
8914 + " does not allow granting of permission to path of Uri "
8920 // Third... does the caller itself have permission to access
8922 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8923 // Require they hold a strong enough Uri permission
8924 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8925 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8926 throw new SecurityException(
8927 "UID " + callingUid + " does not have permission to " + grantUri
8928 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8929 + "or related APIs");
8931 throw new SecurityException(
8932 "UID " + callingUid + " does not have permission to " + grantUri);
8940 * @param uri This uri must NOT contain an embedded userId.
8941 * @param userId The userId in which the uri is to be resolved.
8944 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8945 final int modeFlags, int userId) {
8946 enforceNotIsolatedCaller("checkGrantUriPermission");
8947 synchronized(this) {
8948 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8949 new GrantUri(userId, uri, false), modeFlags, -1);
8953 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8954 final int modeFlags, UriPermissionOwner owner) {
8955 if (!Intent.isAccessUriMode(modeFlags)) {
8959 // So here we are: the caller has the assumed permission
8960 // to the uri, and the target doesn't. Let's now give this to
8963 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8964 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8966 final String authority = grantUri.uri.getAuthority();
8967 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8968 MATCH_DEBUG_TRIAGED_MISSING);
8970 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8974 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8975 grantUri.prefix = true;
8977 final UriPermission perm = findOrCreateUriPermissionLocked(
8978 pi.packageName, targetPkg, targetUid, grantUri);
8979 perm.grantModes(modeFlags, owner);
8982 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8983 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8984 if (targetPkg == null) {
8985 throw new NullPointerException("targetPkg");
8988 final IPackageManager pm = AppGlobals.getPackageManager();
8990 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8991 } catch (RemoteException ex) {
8995 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8997 if (targetUid < 0) {
9001 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9005 static class NeededUriGrants extends ArrayList<GrantUri> {
9006 final String targetPkg;
9007 final int targetUid;
9010 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9011 this.targetPkg = targetPkg;
9012 this.targetUid = targetUid;
9018 * Like checkGrantUriPermissionLocked, but takes an Intent.
9020 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9021 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9022 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9023 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9024 + " clip=" + (intent != null ? intent.getClipData() : null)
9025 + " from " + intent + "; flags=0x"
9026 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9028 if (targetPkg == null) {
9029 throw new NullPointerException("targetPkg");
9032 if (intent == null) {
9035 Uri data = intent.getData();
9036 ClipData clip = intent.getClipData();
9037 if (data == null && clip == null) {
9040 // Default userId for uris in the intent (if they don't specify it themselves)
9041 int contentUserHint = intent.getContentUserHint();
9042 if (contentUserHint == UserHandle.USER_CURRENT) {
9043 contentUserHint = UserHandle.getUserId(callingUid);
9045 final IPackageManager pm = AppGlobals.getPackageManager();
9047 if (needed != null) {
9048 targetUid = needed.targetUid;
9051 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9053 } catch (RemoteException ex) {
9056 if (targetUid < 0) {
9057 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9058 "Can't grant URI permission no uid for: " + targetPkg
9059 + " on user " + targetUserId);
9064 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9065 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9067 if (targetUid > 0) {
9068 if (needed == null) {
9069 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9071 needed.add(grantUri);
9075 for (int i=0; i<clip.getItemCount(); i++) {
9076 Uri uri = clip.getItemAt(i).getUri();
9078 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9079 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9081 if (targetUid > 0) {
9082 if (needed == null) {
9083 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9085 needed.add(grantUri);
9088 Intent clipIntent = clip.getItemAt(i).getIntent();
9089 if (clipIntent != null) {
9090 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9091 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9092 if (newNeeded != null) {
9104 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9106 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9107 UriPermissionOwner owner) {
9108 if (needed != null) {
9109 for (int i=0; i<needed.size(); i++) {
9110 GrantUri grantUri = needed.get(i);
9111 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9112 grantUri, needed.flags, owner);
9117 void grantUriPermissionFromIntentLocked(int callingUid,
9118 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9119 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9120 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9121 if (needed == null) {
9125 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9129 * @param uri This uri must NOT contain an embedded userId.
9130 * @param userId The userId in which the uri is to be resolved.
9133 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9134 final int modeFlags, int userId) {
9135 enforceNotIsolatedCaller("grantUriPermission");
9136 GrantUri grantUri = new GrantUri(userId, uri, false);
9137 synchronized(this) {
9138 final ProcessRecord r = getRecordForAppLocked(caller);
9140 throw new SecurityException("Unable to find app for caller "
9142 + " when granting permission to uri " + grantUri);
9144 if (targetPkg == null) {
9145 throw new IllegalArgumentException("null target");
9147 if (grantUri == null) {
9148 throw new IllegalArgumentException("null uri");
9151 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9152 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9153 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9154 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9156 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9157 UserHandle.getUserId(r.uid));
9161 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9162 if (perm.modeFlags == 0) {
9163 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9165 if (perms != null) {
9166 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9167 "Removing " + perm.targetUid + " permission to " + perm.uri);
9169 perms.remove(perm.uri);
9170 if (perms.isEmpty()) {
9171 mGrantedUriPermissions.remove(perm.targetUid);
9177 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9178 final int modeFlags) {
9179 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9180 "Revoking all granted permissions to " + grantUri);
9182 final IPackageManager pm = AppGlobals.getPackageManager();
9183 final String authority = grantUri.uri.getAuthority();
9184 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9185 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9187 Slog.w(TAG, "No content provider found for permission revoke: "
9188 + grantUri.toSafeString());
9192 // Does the caller have this permission on the URI?
9193 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9194 // If they don't have direct access to the URI, then revoke any
9195 // ownerless URI permissions that have been granted to them.
9196 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9197 if (perms != null) {
9198 boolean persistChanged = false;
9199 for (int i = perms.size()-1; i >= 0; i--) {
9200 final UriPermission perm = perms.valueAt(i);
9201 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9204 if (perm.uri.sourceUserId == grantUri.sourceUserId
9205 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9206 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9207 "Revoking non-owned " + perm.targetUid
9208 + " permission to " + perm.uri);
9209 persistChanged |= perm.revokeModes(
9210 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9211 if (perm.modeFlags == 0) {
9216 if (perms.isEmpty()) {
9217 mGrantedUriPermissions.remove(callingUid);
9219 if (persistChanged) {
9220 schedulePersistUriGrants();
9226 boolean persistChanged = false;
9228 // Go through all of the permissions and remove any that match.
9229 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9230 final int targetUid = mGrantedUriPermissions.keyAt(i);
9231 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9233 for (int j = perms.size()-1; j >= 0; j--) {
9234 final UriPermission perm = perms.valueAt(j);
9235 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9238 if (perm.uri.sourceUserId == grantUri.sourceUserId
9239 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9240 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9241 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9242 persistChanged |= perm.revokeModes(
9243 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9244 targetPackage == null);
9245 if (perm.modeFlags == 0) {
9251 if (perms.isEmpty()) {
9252 mGrantedUriPermissions.removeAt(i);
9256 if (persistChanged) {
9257 schedulePersistUriGrants();
9262 * @param uri This uri must NOT contain an embedded userId.
9263 * @param userId The userId in which the uri is to be resolved.
9266 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9267 final int modeFlags, int userId) {
9268 enforceNotIsolatedCaller("revokeUriPermission");
9269 synchronized(this) {
9270 final ProcessRecord r = getRecordForAppLocked(caller);
9272 throw new SecurityException("Unable to find app for caller "
9274 + " when revoking permission to uri " + uri);
9277 Slog.w(TAG, "revokeUriPermission: null uri");
9281 if (!Intent.isAccessUriMode(modeFlags)) {
9285 final String authority = uri.getAuthority();
9286 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9287 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9289 Slog.w(TAG, "No content provider found for permission revoke: "
9290 + uri.toSafeString());
9294 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9300 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9303 * @param packageName Package name to match, or {@code null} to apply to all
9305 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9307 * @param persistable If persistable grants should be removed.
9309 private void removeUriPermissionsForPackageLocked(
9310 String packageName, int userHandle, boolean persistable) {
9311 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9312 throw new IllegalArgumentException("Must narrow by either package or user");
9315 boolean persistChanged = false;
9317 int N = mGrantedUriPermissions.size();
9318 for (int i = 0; i < N; i++) {
9319 final int targetUid = mGrantedUriPermissions.keyAt(i);
9320 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9322 // Only inspect grants matching user
9323 if (userHandle == UserHandle.USER_ALL
9324 || userHandle == UserHandle.getUserId(targetUid)) {
9325 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9326 final UriPermission perm = it.next();
9328 // Only inspect grants matching package
9329 if (packageName == null || perm.sourcePkg.equals(packageName)
9330 || perm.targetPkg.equals(packageName)) {
9331 // Hacky solution as part of fixing a security bug; ignore
9332 // grants associated with DownloadManager so we don't have
9333 // to immediately launch it to regrant the permissions
9334 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9335 && !persistable) continue;
9337 persistChanged |= perm.revokeModes(persistable
9338 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9340 // Only remove when no modes remain; any persisted grants
9341 // will keep this alive.
9342 if (perm.modeFlags == 0) {
9348 if (perms.isEmpty()) {
9349 mGrantedUriPermissions.remove(targetUid);
9356 if (persistChanged) {
9357 schedulePersistUriGrants();
9362 public IBinder newUriPermissionOwner(String name) {
9363 enforceNotIsolatedCaller("newUriPermissionOwner");
9364 synchronized(this) {
9365 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9366 return owner.getExternalTokenLocked();
9371 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9372 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9373 synchronized(this) {
9374 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9376 throw new IllegalArgumentException("Activity does not exist; token="
9379 return r.getUriPermissionsLocked().getExternalTokenLocked();
9383 * @param uri This uri must NOT contain an embedded userId.
9384 * @param sourceUserId The userId in which the uri is to be resolved.
9385 * @param targetUserId The userId of the app that receives the grant.
9388 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9389 final int modeFlags, int sourceUserId, int targetUserId) {
9390 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9391 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9392 "grantUriPermissionFromOwner", null);
9393 synchronized(this) {
9394 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9395 if (owner == null) {
9396 throw new IllegalArgumentException("Unknown owner: " + token);
9398 if (fromUid != Binder.getCallingUid()) {
9399 if (Binder.getCallingUid() != myUid()) {
9400 // Only system code can grant URI permissions on behalf
9402 throw new SecurityException("nice try");
9405 if (targetPkg == null) {
9406 throw new IllegalArgumentException("null target");
9409 throw new IllegalArgumentException("null uri");
9412 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9413 modeFlags, owner, targetUserId);
9418 * @param uri This uri must NOT contain an embedded userId.
9419 * @param userId The userId in which the uri is to be resolved.
9422 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9423 synchronized(this) {
9424 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9425 if (owner == null) {
9426 throw new IllegalArgumentException("Unknown owner: " + token);
9430 owner.removeUriPermissionsLocked(mode);
9432 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9433 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9438 private void schedulePersistUriGrants() {
9439 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9440 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9441 10 * DateUtils.SECOND_IN_MILLIS);
9445 private void writeGrantedUriPermissions() {
9446 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9448 // Snapshot permissions so we can persist without lock
9449 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9450 synchronized (this) {
9451 final int size = mGrantedUriPermissions.size();
9452 for (int i = 0; i < size; i++) {
9453 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9454 for (UriPermission perm : perms.values()) {
9455 if (perm.persistedModeFlags != 0) {
9456 persist.add(perm.snapshot());
9462 FileOutputStream fos = null;
9464 fos = mGrantFile.startWrite();
9466 XmlSerializer out = new FastXmlSerializer();
9467 out.setOutput(fos, StandardCharsets.UTF_8.name());
9468 out.startDocument(null, true);
9469 out.startTag(null, TAG_URI_GRANTS);
9470 for (UriPermission.Snapshot perm : persist) {
9471 out.startTag(null, TAG_URI_GRANT);
9472 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9473 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9474 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9475 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9476 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9477 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9478 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9479 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9480 out.endTag(null, TAG_URI_GRANT);
9482 out.endTag(null, TAG_URI_GRANTS);
9485 mGrantFile.finishWrite(fos);
9486 } catch (IOException e) {
9488 mGrantFile.failWrite(fos);
9493 private void readGrantedUriPermissionsLocked() {
9494 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9496 final long now = System.currentTimeMillis();
9498 FileInputStream fis = null;
9500 fis = mGrantFile.openRead();
9501 final XmlPullParser in = Xml.newPullParser();
9502 in.setInput(fis, StandardCharsets.UTF_8.name());
9505 while ((type = in.next()) != END_DOCUMENT) {
9506 final String tag = in.getName();
9507 if (type == START_TAG) {
9508 if (TAG_URI_GRANT.equals(tag)) {
9509 final int sourceUserId;
9510 final int targetUserId;
9511 final int userHandle = readIntAttribute(in,
9512 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9513 if (userHandle != UserHandle.USER_NULL) {
9514 // For backwards compatibility.
9515 sourceUserId = userHandle;
9516 targetUserId = userHandle;
9518 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9519 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9521 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9522 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9523 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9524 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9525 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9526 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9528 // Sanity check that provider still belongs to source package
9529 // Both direct boot aware and unaware packages are fine as we
9530 // will do filtering at query time to avoid multiple parsing.
9531 final ProviderInfo pi = getProviderInfoLocked(
9532 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9533 | MATCH_DIRECT_BOOT_UNAWARE);
9534 if (pi != null && sourcePkg.equals(pi.packageName)) {
9537 targetUid = AppGlobals.getPackageManager().getPackageUid(
9538 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9539 } catch (RemoteException e) {
9541 if (targetUid != -1) {
9542 final UriPermission perm = findOrCreateUriPermissionLocked(
9543 sourcePkg, targetPkg, targetUid,
9544 new GrantUri(sourceUserId, uri, prefix));
9545 perm.initPersistedModes(modeFlags, createdTime);
9548 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9549 + " but instead found " + pi);
9554 } catch (FileNotFoundException e) {
9555 // Missing grants is okay
9556 } catch (IOException e) {
9557 Slog.wtf(TAG, "Failed reading Uri grants", e);
9558 } catch (XmlPullParserException e) {
9559 Slog.wtf(TAG, "Failed reading Uri grants", e);
9561 IoUtils.closeQuietly(fis);
9566 * @param uri This uri must NOT contain an embedded userId.
9567 * @param userId The userId in which the uri is to be resolved.
9570 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9571 enforceNotIsolatedCaller("takePersistableUriPermission");
9573 Preconditions.checkFlagsArgument(modeFlags,
9574 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9576 synchronized (this) {
9577 final int callingUid = Binder.getCallingUid();
9578 boolean persistChanged = false;
9579 GrantUri grantUri = new GrantUri(userId, uri, false);
9581 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9582 new GrantUri(userId, uri, false));
9583 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9584 new GrantUri(userId, uri, true));
9586 final boolean exactValid = (exactPerm != null)
9587 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9588 final boolean prefixValid = (prefixPerm != null)
9589 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9591 if (!(exactValid || prefixValid)) {
9592 throw new SecurityException("No persistable permission grants found for UID "
9593 + callingUid + " and Uri " + grantUri.toSafeString());
9597 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9600 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9603 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9605 if (persistChanged) {
9606 schedulePersistUriGrants();
9612 * @param uri This uri must NOT contain an embedded userId.
9613 * @param userId The userId in which the uri is to be resolved.
9616 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9617 enforceNotIsolatedCaller("releasePersistableUriPermission");
9619 Preconditions.checkFlagsArgument(modeFlags,
9620 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9622 synchronized (this) {
9623 final int callingUid = Binder.getCallingUid();
9624 boolean persistChanged = false;
9626 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9627 new GrantUri(userId, uri, false));
9628 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9629 new GrantUri(userId, uri, true));
9630 if (exactPerm == null && prefixPerm == null) {
9631 throw new SecurityException("No permission grants found for UID " + callingUid
9632 + " and Uri " + uri.toSafeString());
9635 if (exactPerm != null) {
9636 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9637 removeUriPermissionIfNeededLocked(exactPerm);
9639 if (prefixPerm != null) {
9640 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9641 removeUriPermissionIfNeededLocked(prefixPerm);
9644 if (persistChanged) {
9645 schedulePersistUriGrants();
9651 * Prune any older {@link UriPermission} for the given UID until outstanding
9652 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9654 * @return if any mutations occured that require persisting.
9656 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9657 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9658 if (perms == null) return false;
9659 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9661 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9662 for (UriPermission perm : perms.values()) {
9663 if (perm.persistedModeFlags != 0) {
9664 persisted.add(perm);
9668 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9669 if (trimCount <= 0) return false;
9671 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9672 for (int i = 0; i < trimCount; i++) {
9673 final UriPermission perm = persisted.get(i);
9675 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9676 "Trimming grant created at " + perm.persistedCreateTime);
9678 perm.releasePersistableModes(~0);
9679 removeUriPermissionIfNeededLocked(perm);
9686 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9687 String packageName, boolean incoming) {
9688 enforceNotIsolatedCaller("getPersistedUriPermissions");
9689 Preconditions.checkNotNull(packageName, "packageName");
9691 final int callingUid = Binder.getCallingUid();
9692 final int callingUserId = UserHandle.getUserId(callingUid);
9693 final IPackageManager pm = AppGlobals.getPackageManager();
9695 final int packageUid = pm.getPackageUid(packageName,
9696 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9697 if (packageUid != callingUid) {
9698 throw new SecurityException(
9699 "Package " + packageName + " does not belong to calling UID " + callingUid);
9701 } catch (RemoteException e) {
9702 throw new SecurityException("Failed to verify package name ownership");
9705 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9706 synchronized (this) {
9708 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9710 if (perms == null) {
9711 Slog.w(TAG, "No permission grants found for " + packageName);
9713 for (UriPermission perm : perms.values()) {
9714 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9715 result.add(perm.buildPersistedPublicApiObject());
9720 final int size = mGrantedUriPermissions.size();
9721 for (int i = 0; i < size; i++) {
9722 final ArrayMap<GrantUri, UriPermission> perms =
9723 mGrantedUriPermissions.valueAt(i);
9724 for (UriPermission perm : perms.values()) {
9725 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9726 result.add(perm.buildPersistedPublicApiObject());
9732 return new ParceledListSlice<android.content.UriPermission>(result);
9736 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9737 String packageName, int userId) {
9738 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9739 "getGrantedUriPermissions");
9741 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9742 synchronized (this) {
9743 final int size = mGrantedUriPermissions.size();
9744 for (int i = 0; i < size; i++) {
9745 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9746 for (UriPermission perm : perms.values()) {
9747 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9748 && perm.persistedModeFlags != 0) {
9749 result.add(perm.buildPersistedPublicApiObject());
9754 return new ParceledListSlice<android.content.UriPermission>(result);
9758 public void clearGrantedUriPermissions(String packageName, int userId) {
9759 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9760 "clearGrantedUriPermissions");
9761 removeUriPermissionsForPackageLocked(packageName, userId, true);
9765 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9766 synchronized (this) {
9768 who != null ? getRecordForAppLocked(who) : null;
9769 if (app == null) return;
9771 Message msg = Message.obtain();
9772 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9774 msg.arg1 = waiting ? 1 : 0;
9775 mUiHandler.sendMessage(msg);
9780 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9781 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9782 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9783 outInfo.availMem = getFreeMemory();
9784 outInfo.totalMem = getTotalMemory();
9785 outInfo.threshold = homeAppMem;
9786 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9787 outInfo.hiddenAppThreshold = cachedAppMem;
9788 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9789 ProcessList.SERVICE_ADJ);
9790 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9791 ProcessList.VISIBLE_APP_ADJ);
9792 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9793 ProcessList.FOREGROUND_APP_ADJ);
9796 // =========================================================
9798 // =========================================================
9801 public List<IBinder> getAppTasks(String callingPackage) {
9802 int callingUid = Binder.getCallingUid();
9803 long ident = Binder.clearCallingIdentity();
9805 synchronized(this) {
9806 ArrayList<IBinder> list = new ArrayList<IBinder>();
9808 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9810 final int N = mRecentTasks.size();
9811 for (int i = 0; i < N; i++) {
9812 TaskRecord tr = mRecentTasks.get(i);
9813 // Skip tasks that do not match the caller. We don't need to verify
9814 // callingPackage, because we are also limiting to callingUid and know
9815 // that will limit to the correct security sandbox.
9816 if (tr.effectiveUid != callingUid) {
9819 Intent intent = tr.getBaseIntent();
9820 if (intent == null ||
9821 !callingPackage.equals(intent.getComponent().getPackageName())) {
9824 ActivityManager.RecentTaskInfo taskInfo =
9825 createRecentTaskInfoFromTaskRecord(tr);
9826 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9827 list.add(taskImpl.asBinder());
9830 Binder.restoreCallingIdentity(ident);
9837 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9838 final int callingUid = Binder.getCallingUid();
9839 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9841 synchronized(this) {
9842 if (DEBUG_ALL) Slog.v(
9843 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9845 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9848 // TODO: Improve with MRU list from all ActivityStacks.
9849 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9856 * Creates a new RecentTaskInfo from a TaskRecord.
9858 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9859 // Update the task description to reflect any changes in the task stack
9860 tr.updateTaskDescription();
9862 // Compose the recent task info
9863 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9864 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9865 rti.persistentId = tr.taskId;
9866 rti.baseIntent = new Intent(tr.getBaseIntent());
9867 rti.origActivity = tr.origActivity;
9868 rti.realActivity = tr.realActivity;
9869 rti.description = tr.lastDescription;
9870 rti.stackId = tr.getStackId();
9871 rti.userId = tr.userId;
9872 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9873 rti.firstActiveTime = tr.firstActiveTime;
9874 rti.lastActiveTime = tr.lastActiveTime;
9875 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9876 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9877 rti.numActivities = 0;
9878 if (tr.mBounds != null) {
9879 rti.bounds = new Rect(tr.mBounds);
9881 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9882 rti.resizeMode = tr.mResizeMode;
9884 ActivityRecord base = null;
9885 ActivityRecord top = null;
9888 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9889 tmp = tr.mActivities.get(i);
9890 if (tmp.finishing) {
9894 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9897 rti.numActivities++;
9900 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9901 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9906 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9907 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9908 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9910 if (checkPermission(android.Manifest.permission.GET_TASKS,
9911 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9912 // Temporary compatibility: some existing apps on the system image may
9913 // still be requesting the old permission and not switched to the new
9914 // one; if so, we'll still allow them full access. This means we need
9915 // to see if they are holding the old permission and are a system app.
9917 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9919 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9920 + " is using old GET_TASKS but privileged; allowing");
9922 } catch (RemoteException e) {
9927 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9928 + " does not hold REAL_GET_TASKS; limiting output");
9934 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9936 final int callingUid = Binder.getCallingUid();
9937 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9938 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9940 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9941 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9942 synchronized (this) {
9943 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9945 final boolean detailed = checkCallingPermission(
9946 android.Manifest.permission.GET_DETAILED_TASKS)
9947 == PackageManager.PERMISSION_GRANTED;
9949 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9950 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9951 return ParceledListSlice.emptyList();
9953 mRecentTasks.loadUserRecentsLocked(userId);
9955 final int recentsCount = mRecentTasks.size();
9956 ArrayList<ActivityManager.RecentTaskInfo> res =
9957 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9959 final Set<Integer> includedUsers;
9960 if (includeProfiles) {
9961 includedUsers = mUserController.getProfileIds(userId);
9963 includedUsers = new HashSet<>();
9965 includedUsers.add(Integer.valueOf(userId));
9967 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9968 TaskRecord tr = mRecentTasks.get(i);
9969 // Only add calling user or related users recent tasks
9970 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9971 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9975 if (tr.realActivitySuspended) {
9976 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9980 // Return the entry if desired by the caller. We always return
9981 // the first entry, because callers always expect this to be the
9982 // foreground app. We may filter others if the caller has
9983 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9984 // we should exclude the entry.
9988 || (tr.intent == null)
9989 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9992 // If the caller doesn't have the GET_TASKS permission, then only
9993 // allow them to see a small subset of tasks -- their own and home.
9994 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9995 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9999 final ActivityStack stack = tr.getStack();
10000 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
10001 if (stack != null && stack.isHomeOrRecentsStack()) {
10002 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10003 "Skipping, home or recents stack task: " + tr);
10007 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10008 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10009 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10010 "Skipping, top task in docked stack: " + tr);
10014 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10015 if (stack != null && stack.isPinnedStack()) {
10016 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10017 "Skipping, pinned stack task: " + tr);
10021 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10022 // Don't include auto remove tasks that are finished or finishing.
10023 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10024 "Skipping, auto-remove without activity: " + tr);
10027 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10028 && !tr.isAvailable) {
10029 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10030 "Skipping, unavail real act: " + tr);
10034 if (!tr.mUserSetupComplete) {
10035 // Don't include task launched while user is not done setting-up.
10036 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10037 "Skipping, user setup not complete: " + tr);
10041 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10043 rti.baseIntent.replaceExtras((Bundle)null);
10050 return new ParceledListSlice<>(res);
10055 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10056 synchronized (this) {
10057 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10058 "getTaskThumbnail()");
10059 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10060 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10062 return tr.getTaskThumbnailLocked();
10069 public ActivityManager.TaskDescription getTaskDescription(int id) {
10070 synchronized (this) {
10071 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10072 "getTaskDescription()");
10073 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10074 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10076 return tr.lastTaskDescription;
10083 public int addAppTask(IBinder activityToken, Intent intent,
10084 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10085 final int callingUid = Binder.getCallingUid();
10086 final long callingIdent = Binder.clearCallingIdentity();
10089 synchronized (this) {
10090 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10092 throw new IllegalArgumentException("Activity does not exist; token="
10095 ComponentName comp = intent.getComponent();
10096 if (comp == null) {
10097 throw new IllegalArgumentException("Intent " + intent
10098 + " must specify explicit component");
10100 if (thumbnail.getWidth() != mThumbnailWidth
10101 || thumbnail.getHeight() != mThumbnailHeight) {
10102 throw new IllegalArgumentException("Bad thumbnail size: got "
10103 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10104 + mThumbnailWidth + "x" + mThumbnailHeight);
10106 if (intent.getSelector() != null) {
10107 intent.setSelector(null);
10109 if (intent.getSourceBounds() != null) {
10110 intent.setSourceBounds(null);
10112 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10113 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10114 // The caller has added this as an auto-remove task... that makes no
10115 // sense, so turn off auto-remove.
10116 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10119 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10120 mLastAddedTaskActivity = null;
10122 ActivityInfo ainfo = mLastAddedTaskActivity;
10123 if (ainfo == null) {
10124 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10125 comp, 0, UserHandle.getUserId(callingUid));
10126 if (ainfo.applicationInfo.uid != callingUid) {
10127 throw new SecurityException(
10128 "Can't add task for another application: target uid="
10129 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10133 TaskRecord task = new TaskRecord(this,
10134 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10135 ainfo, intent, description, new TaskThumbnailInfo());
10137 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10138 if (trimIdx >= 0) {
10139 // If this would have caused a trim, then we'll abort because that
10140 // means it would be added at the end of the list but then just removed.
10141 return INVALID_TASK_ID;
10144 final int N = mRecentTasks.size();
10145 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10146 final TaskRecord tr = mRecentTasks.remove(N - 1);
10147 tr.removedFromRecents();
10150 task.inRecents = true;
10151 mRecentTasks.add(task);
10152 r.getStack().addTask(task, false, "addAppTask");
10154 task.setLastThumbnailLocked(thumbnail);
10155 task.freeLastThumbnail();
10156 return task.taskId;
10159 Binder.restoreCallingIdentity(callingIdent);
10164 public Point getAppTaskThumbnailSize() {
10165 synchronized (this) {
10166 return new Point(mThumbnailWidth, mThumbnailHeight);
10171 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10172 synchronized (this) {
10173 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10175 r.setTaskDescription(td);
10176 final TaskRecord task = r.getTask();
10177 task.updateTaskDescription();
10178 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10184 public void setTaskResizeable(int taskId, int resizeableMode) {
10185 synchronized (this) {
10186 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10187 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10188 if (task == null) {
10189 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10192 task.setResizeMode(resizeableMode);
10197 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10198 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10199 long ident = Binder.clearCallingIdentity();
10201 synchronized (this) {
10202 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10203 if (task == null) {
10204 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10207 // Place the task in the right stack if it isn't there already based on
10208 // the requested bounds.
10209 // The stack transition logic is:
10210 // - a null bounds on a freeform task moves that task to fullscreen
10211 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10212 // that task to freeform
10213 // - otherwise the task is not moved
10214 int stackId = task.getStackId();
10215 if (!StackId.isTaskResizeAllowed(stackId)) {
10216 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10218 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10219 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10220 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10221 stackId = FREEFORM_WORKSPACE_STACK_ID;
10224 // Reparent the task to the right stack if necessary
10225 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10226 if (stackId != task.getStackId()) {
10227 // Defer resume until the task is resized below
10228 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10229 DEFER_RESUME, "resizeTask");
10230 preserveWindow = false;
10233 // After reparenting (which only resizes the task to the stack bounds), resize the
10234 // task to the actual bounds provided
10235 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10238 Binder.restoreCallingIdentity(ident);
10243 public Rect getTaskBounds(int taskId) {
10244 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10245 long ident = Binder.clearCallingIdentity();
10246 Rect rect = new Rect();
10248 synchronized (this) {
10249 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10250 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10251 if (task == null) {
10252 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10255 if (task.getStack() != null) {
10256 // Return the bounds from window manager since it will be adjusted for various
10257 // things like the presense of a docked stack for tasks that aren't resizeable.
10258 task.getWindowContainerBounds(rect);
10260 // Task isn't in window manager yet since it isn't associated with a stack.
10261 // Return the persist value from activity manager
10262 if (task.mBounds != null) {
10263 rect.set(task.mBounds);
10264 } else if (task.mLastNonFullscreenBounds != null) {
10265 rect.set(task.mLastNonFullscreenBounds);
10270 Binder.restoreCallingIdentity(ident);
10276 public void cancelTaskWindowTransition(int taskId) {
10277 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10278 final long ident = Binder.clearCallingIdentity();
10280 synchronized (this) {
10281 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10282 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10283 if (task == null) {
10284 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10287 task.cancelWindowTransition();
10290 Binder.restoreCallingIdentity(ident);
10295 public void cancelTaskThumbnailTransition(int taskId) {
10296 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10297 final long ident = Binder.clearCallingIdentity();
10299 synchronized (this) {
10300 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10301 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10302 if (task == null) {
10303 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10306 task.cancelThumbnailTransition();
10309 Binder.restoreCallingIdentity(ident);
10314 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10315 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10316 final long ident = Binder.clearCallingIdentity();
10318 final TaskRecord task;
10319 synchronized (this) {
10320 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10321 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10322 if (task == null) {
10323 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10327 // Don't call this while holding the lock as this operation might hit the disk.
10328 return task.getSnapshot(reducedResolution);
10330 Binder.restoreCallingIdentity(ident);
10335 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10336 if (userId != UserHandle.getCallingUserId()) {
10337 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10338 "getTaskDescriptionIcon");
10340 final File passedIconFile = new File(filePath);
10341 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10342 passedIconFile.getName());
10343 if (!legitIconFile.getPath().equals(filePath)
10344 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10345 throw new IllegalArgumentException("Bad file path: " + filePath
10346 + " passed for userId " + userId);
10348 return mRecentTasks.getTaskDescriptionIcon(filePath);
10352 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10353 throws RemoteException {
10354 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10355 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10356 activityOptions.getCustomInPlaceResId() == 0) {
10357 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10358 "with valid animation");
10360 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10361 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10362 activityOptions.getCustomInPlaceResId());
10363 mWindowManager.executeAppTransition();
10366 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10367 // Remove all tasks with activities in the specified package from the list of recent tasks
10368 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10369 TaskRecord tr = mRecentTasks.get(i);
10370 if (tr.userId != userId) continue;
10372 ComponentName cn = tr.intent.getComponent();
10373 if (cn != null && cn.getPackageName().equals(packageName)) {
10374 // If the package name matches, remove the task.
10375 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10380 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10383 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10384 TaskRecord tr = mRecentTasks.get(i);
10385 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10389 ComponentName cn = tr.intent.getComponent();
10390 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10391 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10392 if (sameComponent) {
10393 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10399 public void removeStack(int stackId) {
10400 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10401 if (StackId.isHomeOrRecentsStack(stackId)) {
10402 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10405 synchronized (this) {
10406 final long ident = Binder.clearCallingIdentity();
10408 mStackSupervisor.removeStackLocked(stackId);
10410 Binder.restoreCallingIdentity(ident);
10416 public void moveStackToDisplay(int stackId, int displayId) {
10417 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10419 synchronized (this) {
10420 final long ident = Binder.clearCallingIdentity();
10422 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10423 + " to displayId=" + displayId);
10424 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10426 Binder.restoreCallingIdentity(ident);
10432 public boolean removeTask(int taskId) {
10433 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10434 synchronized (this) {
10435 final long ident = Binder.clearCallingIdentity();
10437 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10439 Binder.restoreCallingIdentity(ident);
10445 * TODO: Add mController hook
10448 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10449 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10451 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10452 synchronized(this) {
10453 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10457 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10458 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10460 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10461 Binder.getCallingUid(), -1, -1, "Task to front")) {
10462 ActivityOptions.abort(options);
10465 final long origId = Binder.clearCallingIdentity();
10467 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10468 if (task == null) {
10469 Slog.d(TAG, "Could not find task for id: "+ taskId);
10472 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10473 mStackSupervisor.showLockTaskToast();
10474 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10477 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10478 if (prev != null) {
10479 task.setTaskToReturnTo(prev);
10481 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10482 false /* forceNonResizable */);
10484 final ActivityRecord topActivity = task.getTopActivity();
10485 if (topActivity != null) {
10487 // We are reshowing a task, use a starting window to hide the initial draw delay
10488 // so the transition can start earlier.
10489 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10490 true /* taskSwitch */, fromRecents);
10493 Binder.restoreCallingIdentity(origId);
10495 ActivityOptions.abort(options);
10499 * Attempts to move a task backwards in z-order (the order of activities within the task is
10502 * There are several possible results of this call:
10503 * - if the task is locked, then we will show the lock toast
10504 * - if there is a task behind the provided task, then that task is made visible and resumed as
10505 * this task is moved to the back
10506 * - otherwise, if there are no other tasks in the stack:
10507 * - if this task is in the pinned stack, then we remove the stack completely, which will
10508 * have the effect of moving the task to the top or bottom of the fullscreen stack
10509 * (depending on whether it is visible)
10510 * - otherwise, we simply return home and hide this task
10512 * @param token A reference to the activity we wish to move
10513 * @param nonRoot If false then this only works if the activity is the root
10514 * of a task; if true it will work for any activity in a task.
10515 * @return Returns true if the move completed, false if not.
10518 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10519 enforceNotIsolatedCaller("moveActivityTaskToBack");
10520 synchronized(this) {
10521 final long origId = Binder.clearCallingIdentity();
10523 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10524 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10525 if (task != null) {
10526 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10529 Binder.restoreCallingIdentity(origId);
10536 public void moveTaskBackwards(int task) {
10537 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10538 "moveTaskBackwards()");
10540 synchronized(this) {
10541 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10542 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10545 final long origId = Binder.clearCallingIdentity();
10546 moveTaskBackwardsLocked(task);
10547 Binder.restoreCallingIdentity(origId);
10551 private final void moveTaskBackwardsLocked(int task) {
10552 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10556 public int createStackOnDisplay(int displayId) throws RemoteException {
10557 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10558 synchronized (this) {
10559 final int stackId = mStackSupervisor.getNextStackId();
10560 final ActivityStack stack =
10561 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10562 if (stack == null) {
10563 return INVALID_STACK_ID;
10565 return stack.mStackId;
10570 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10571 synchronized (this) {
10572 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10573 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10574 return stack.mDisplayId;
10576 return DEFAULT_DISPLAY;
10581 public int getActivityStackId(IBinder token) throws RemoteException {
10582 synchronized (this) {
10583 ActivityStack stack = ActivityRecord.getStackLocked(token);
10584 if (stack == null) {
10585 return INVALID_STACK_ID;
10587 return stack.mStackId;
10592 public void exitFreeformMode(IBinder token) throws RemoteException {
10593 synchronized (this) {
10594 long ident = Binder.clearCallingIdentity();
10596 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10598 throw new IllegalArgumentException(
10599 "exitFreeformMode: No activity record matching token=" + token);
10602 final ActivityStack stack = r.getStack();
10603 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10604 throw new IllegalStateException(
10605 "exitFreeformMode: You can only go fullscreen from freeform.");
10608 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10609 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10610 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10612 Binder.restoreCallingIdentity(ident);
10618 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10619 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10620 if (StackId.isHomeOrRecentsStack(stackId)) {
10621 throw new IllegalArgumentException(
10622 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10624 synchronized (this) {
10625 long ident = Binder.clearCallingIdentity();
10627 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10628 if (task == null) {
10629 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10633 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10634 + " to stackId=" + stackId + " toTop=" + toTop);
10635 if (stackId == DOCKED_STACK_ID) {
10636 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10637 null /* initialBounds */);
10639 task.reparent(stackId, toTop,
10640 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10642 Binder.restoreCallingIdentity(ident);
10648 public void swapDockedAndFullscreenStack() throws RemoteException {
10649 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10650 synchronized (this) {
10651 long ident = Binder.clearCallingIdentity();
10653 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10654 FULLSCREEN_WORKSPACE_STACK_ID);
10655 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10657 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10658 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10660 if (topTask == null || tasks == null || tasks.size() == 0) {
10662 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10666 // TODO: App transition
10667 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10669 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10670 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10671 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10672 final int size = tasks.size();
10673 for (int i = 0; i < size; i++) {
10674 final int id = tasks.get(i).taskId;
10675 if (id == topTask.taskId) {
10679 // Defer the resume until after all the tasks have been moved
10680 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10681 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10682 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10685 // Because we deferred the resume to avoid conflicts with stack switches while
10686 // resuming, we need to do it after all the tasks are moved.
10687 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10688 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10690 mWindowManager.executeAppTransition();
10692 Binder.restoreCallingIdentity(ident);
10698 * Moves the input task to the docked stack.
10700 * @param taskId Id of task to move.
10701 * @param createMode The mode the docked stack should be created in if it doesn't exist
10703 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10705 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10706 * @param toTop If the task and stack should be moved to the top.
10707 * @param animate Whether we should play an animation for the moving the task
10708 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10709 * docked stack. Pass {@code null} to use default bounds.
10712 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10713 Rect initialBounds) {
10714 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10715 synchronized (this) {
10716 long ident = Binder.clearCallingIdentity();
10718 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10719 if (task == null) {
10720 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10724 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10725 + " to createMode=" + createMode + " toTop=" + toTop);
10726 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10728 // Defer resuming until we move the home stack to the front below
10729 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10730 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10731 "moveTaskToDockedStack");
10733 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10737 Binder.restoreCallingIdentity(ident);
10743 * Moves the top activity in the input stackId to the pinned stack.
10745 * @param stackId Id of stack to move the top activity to pinned stack.
10746 * @param bounds Bounds to use for pinned stack.
10748 * @return True if the top activity of the input stack was successfully moved to the pinned
10752 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10753 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10754 synchronized (this) {
10755 if (!mSupportsPictureInPicture) {
10756 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10757 + "Device doesn't support picture-in-picture mode");
10760 long ident = Binder.clearCallingIdentity();
10762 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10764 Binder.restoreCallingIdentity(ident);
10770 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10771 boolean preserveWindows, boolean animate, int animationDuration) {
10772 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10773 long ident = Binder.clearCallingIdentity();
10775 synchronized (this) {
10777 if (stackId == PINNED_STACK_ID) {
10778 final PinnedActivityStack pinnedStack =
10779 mStackSupervisor.getStack(PINNED_STACK_ID);
10780 if (pinnedStack != null) {
10781 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10782 destBounds, animationDuration, false /* fromFullscreen */);
10785 throw new IllegalArgumentException("Stack: " + stackId
10786 + " doesn't support animated resize.");
10789 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10790 null /* tempTaskInsetBounds */, preserveWindows,
10791 allowResizeInDockedMode, !DEFER_RESUME);
10795 Binder.restoreCallingIdentity(ident);
10800 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10801 Rect tempDockedTaskInsetBounds,
10802 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10803 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10804 "resizeDockedStack()");
10805 long ident = Binder.clearCallingIdentity();
10807 synchronized (this) {
10808 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10809 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10813 Binder.restoreCallingIdentity(ident);
10818 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10819 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10820 "resizePinnedStack()");
10821 final long ident = Binder.clearCallingIdentity();
10823 synchronized (this) {
10824 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10827 Binder.restoreCallingIdentity(ident);
10832 * Try to place task to provided position. The final position might be different depending on
10833 * current user and stacks state. The task will be moved to target stack if it's currently in
10837 public void positionTaskInStack(int taskId, int stackId, int position) {
10838 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10839 if (StackId.isHomeOrRecentsStack(stackId)) {
10840 throw new IllegalArgumentException(
10841 "positionTaskInStack: Attempt to change the position of task "
10842 + taskId + " in/to home/recents stack");
10844 synchronized (this) {
10845 long ident = Binder.clearCallingIdentity();
10847 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10848 + taskId + " in stackId=" + stackId + " at position=" + position);
10849 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10850 if (task == null) {
10851 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10855 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10858 // TODO: Have the callers of this API call a separate reparent method if that is
10859 // what they intended to do vs. having this method also do reparenting.
10860 if (task.getStack() == stack) {
10861 // Change position in current stack.
10862 stack.positionChildAt(task, position);
10864 // Reparent to new stack.
10865 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10866 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10869 Binder.restoreCallingIdentity(ident);
10875 public List<StackInfo> getAllStackInfos() {
10876 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10877 long ident = Binder.clearCallingIdentity();
10879 synchronized (this) {
10880 return mStackSupervisor.getAllStackInfosLocked();
10883 Binder.restoreCallingIdentity(ident);
10888 public StackInfo getStackInfo(int stackId) {
10889 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10890 long ident = Binder.clearCallingIdentity();
10892 synchronized (this) {
10893 return mStackSupervisor.getStackInfoLocked(stackId);
10896 Binder.restoreCallingIdentity(ident);
10901 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10902 synchronized(this) {
10903 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10908 public void updateDeviceOwner(String packageName) {
10909 final int callingUid = Binder.getCallingUid();
10910 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10911 throw new SecurityException("updateDeviceOwner called from non-system process");
10913 synchronized (this) {
10914 mDeviceOwnerName = packageName;
10919 public void updateLockTaskPackages(int userId, String[] packages) {
10920 final int callingUid = Binder.getCallingUid();
10921 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10922 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10923 "updateLockTaskPackages()");
10925 synchronized (this) {
10926 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10927 Arrays.toString(packages));
10928 mLockTaskPackages.put(userId, packages);
10929 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10934 void startLockTaskModeLocked(TaskRecord task) {
10935 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10936 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10940 // When a task is locked, dismiss the pinned stack if it exists
10941 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10943 if (pinnedStack != null) {
10944 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10947 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10948 // is initiated by system after the pinning request was shown and locked mode is initiated
10949 // by an authorized app directly
10950 final int callingUid = Binder.getCallingUid();
10951 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10952 long ident = Binder.clearCallingIdentity();
10954 if (!isSystemInitiated) {
10955 task.mLockTaskUid = callingUid;
10956 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10957 // startLockTask() called by app and task mode is lockTaskModeDefault.
10958 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10959 StatusBarManagerInternal statusBarManager =
10960 LocalServices.getService(StatusBarManagerInternal.class);
10961 if (statusBarManager != null) {
10962 statusBarManager.showScreenPinningRequest(task.taskId);
10967 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10968 if (stack == null || task != stack.topTask()) {
10969 throw new IllegalArgumentException("Invalid task, not in foreground");
10972 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10974 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10975 ActivityManager.LOCK_TASK_MODE_PINNED :
10976 ActivityManager.LOCK_TASK_MODE_LOCKED,
10977 "startLockTask", true);
10979 Binder.restoreCallingIdentity(ident);
10984 public void startLockTaskModeById(int taskId) {
10985 synchronized (this) {
10986 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10987 if (task != null) {
10988 startLockTaskModeLocked(task);
10994 public void startLockTaskModeByToken(IBinder token) {
10995 synchronized (this) {
10996 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11000 final TaskRecord task = r.getTask();
11001 if (task != null) {
11002 startLockTaskModeLocked(task);
11008 public void startSystemLockTaskMode(int taskId) throws RemoteException {
11009 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11010 // This makes inner call to look as if it was initiated by system.
11011 long ident = Binder.clearCallingIdentity();
11013 synchronized (this) {
11014 startLockTaskModeById(taskId);
11017 Binder.restoreCallingIdentity(ident);
11022 public void stopLockTaskMode() {
11023 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11024 if (lockTask == null) {
11025 // Our work here is done.
11029 final int callingUid = Binder.getCallingUid();
11030 final int lockTaskUid = lockTask.mLockTaskUid;
11031 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11032 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11036 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11037 // It is possible lockTaskMode was started by the system process because
11038 // android:lockTaskMode is set to a locking value in the application manifest
11039 // instead of the app calling startLockTaskMode. In this case
11040 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11041 // {@link TaskRecord.effectiveUid} instead. Also caller with
11042 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11043 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11044 && callingUid != lockTaskUid
11045 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11046 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11047 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11050 long ident = Binder.clearCallingIdentity();
11052 Log.d(TAG, "stopLockTaskMode");
11054 synchronized (this) {
11055 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11056 "stopLockTask", true);
11058 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11060 tm.showInCallScreen(false);
11063 Binder.restoreCallingIdentity(ident);
11068 * This API should be called by SystemUI only when user perform certain action to dismiss
11069 * lock task mode. We should only dismiss pinned lock task mode in this case.
11072 public void stopSystemLockTaskMode() throws RemoteException {
11073 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11074 stopLockTaskMode();
11076 mStackSupervisor.showLockTaskToast();
11081 public boolean isInLockTaskMode() {
11082 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11086 public int getLockTaskModeState() {
11087 synchronized (this) {
11088 return mStackSupervisor.getLockTaskModeState();
11093 public void showLockTaskEscapeMessage(IBinder token) {
11094 synchronized (this) {
11095 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11099 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11104 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11105 throws RemoteException {
11106 synchronized (this) {
11107 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11109 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11113 final long origId = Binder.clearCallingIdentity();
11115 r.setDisablePreviewScreenshots(disable);
11117 Binder.restoreCallingIdentity(origId);
11122 // =========================================================
11123 // CONTENT PROVIDERS
11124 // =========================================================
11126 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11127 List<ProviderInfo> providers = null;
11129 providers = AppGlobals.getPackageManager()
11130 .queryContentProviders(app.processName, app.uid,
11131 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11132 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11134 } catch (RemoteException ex) {
11136 if (DEBUG_MU) Slog.v(TAG_MU,
11137 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11138 int userId = app.userId;
11139 if (providers != null) {
11140 int N = providers.size();
11141 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11142 for (int i=0; i<N; i++) {
11143 // TODO: keep logic in sync with installEncryptionUnawareProviders
11145 (ProviderInfo)providers.get(i);
11146 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11147 cpi.name, cpi.flags);
11148 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11149 // This is a singleton provider, but a user besides the
11150 // default user is asking to initialize a process it runs
11151 // in... well, no, it doesn't actually run in this process,
11152 // it runs in the process of the default user. Get rid of it.
11153 providers.remove(i);
11159 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11160 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11162 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11163 mProviderMap.putProviderByClass(comp, cpr);
11165 if (DEBUG_MU) Slog.v(TAG_MU,
11166 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11167 app.pubProviders.put(cpi.name, cpr);
11168 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11169 // Don't add this if it is a platform component that is marked
11170 // to run in multiple processes, because this is actually
11171 // part of the framework so doesn't make sense to track as a
11172 // separate apk in the process.
11173 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11176 notifyPackageUse(cpi.applicationInfo.packageName,
11177 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11184 * Check if the calling UID has a possible chance at accessing the provider
11185 * at the given authority and user.
11187 public String checkContentProviderAccess(String authority, int userId) {
11188 if (userId == UserHandle.USER_ALL) {
11189 mContext.enforceCallingOrSelfPermission(
11190 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11191 userId = UserHandle.getCallingUserId();
11194 ProviderInfo cpi = null;
11196 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11197 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11198 | PackageManager.MATCH_DISABLED_COMPONENTS
11199 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11200 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11202 } catch (RemoteException ignored) {
11205 return "Failed to find provider " + authority + " for user " + userId
11206 + "; expected to find a valid ContentProvider for this authority";
11209 ProcessRecord r = null;
11210 synchronized (mPidsSelfLocked) {
11211 r = mPidsSelfLocked.get(Binder.getCallingPid());
11214 return "Failed to find PID " + Binder.getCallingPid();
11217 synchronized (this) {
11218 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11223 * Check if {@link ProcessRecord} has a possible chance at accessing the
11224 * given {@link ProviderInfo}. Final permission checking is always done
11225 * in {@link ContentProvider}.
11227 private final String checkContentProviderPermissionLocked(
11228 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11229 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11230 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11231 boolean checkedGrants = false;
11233 // Looking for cross-user grants before enforcing the typical cross-users permissions
11234 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11235 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11236 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11239 checkedGrants = true;
11241 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11242 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11243 if (userId != tmpTargetUserId) {
11244 // When we actually went to determine the final targer user ID, this ended
11245 // up different than our initial check for the authority. This is because
11246 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11247 // SELF. So we need to re-check the grants again.
11248 checkedGrants = false;
11251 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11252 cpi.applicationInfo.uid, cpi.exported)
11253 == PackageManager.PERMISSION_GRANTED) {
11256 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11257 cpi.applicationInfo.uid, cpi.exported)
11258 == PackageManager.PERMISSION_GRANTED) {
11262 PathPermission[] pps = cpi.pathPermissions;
11264 int i = pps.length;
11267 PathPermission pp = pps[i];
11268 String pprperm = pp.getReadPermission();
11269 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11270 cpi.applicationInfo.uid, cpi.exported)
11271 == PackageManager.PERMISSION_GRANTED) {
11274 String ppwperm = pp.getWritePermission();
11275 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11276 cpi.applicationInfo.uid, cpi.exported)
11277 == PackageManager.PERMISSION_GRANTED) {
11282 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11286 final String suffix;
11287 if (!cpi.exported) {
11288 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11289 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11290 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11292 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11294 final String msg = "Permission Denial: opening provider " + cpi.name
11295 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11296 + ", uid=" + callingUid + ")" + suffix;
11302 * Returns if the ContentProvider has granted a uri to callingUid
11304 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11305 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11306 if (perms != null) {
11307 for (int i=perms.size()-1; i>=0; i--) {
11308 GrantUri grantUri = perms.keyAt(i);
11309 if (grantUri.sourceUserId == userId || !checkUser) {
11310 if (matchesProvider(grantUri.uri, cpi)) {
11320 * Returns true if the uri authority is one of the authorities specified in the provider.
11322 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11323 String uriAuth = uri.getAuthority();
11324 String cpiAuth = cpi.authority;
11325 if (cpiAuth.indexOf(';') == -1) {
11326 return cpiAuth.equals(uriAuth);
11328 String[] cpiAuths = cpiAuth.split(";");
11329 int length = cpiAuths.length;
11330 for (int i = 0; i < length; i++) {
11331 if (cpiAuths[i].equals(uriAuth)) return true;
11336 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11337 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11339 for (int i=0; i<r.conProviders.size(); i++) {
11340 ContentProviderConnection conn = r.conProviders.get(i);
11341 if (conn.provider == cpr) {
11342 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11343 "Adding provider requested by "
11344 + r.processName + " from process "
11345 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11346 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11348 conn.stableCount++;
11349 conn.numStableIncs++;
11351 conn.unstableCount++;
11352 conn.numUnstableIncs++;
11357 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11359 conn.stableCount = 1;
11360 conn.numStableIncs = 1;
11362 conn.unstableCount = 1;
11363 conn.numUnstableIncs = 1;
11365 cpr.connections.add(conn);
11366 r.conProviders.add(conn);
11367 startAssociationLocked(r.uid, r.processName, r.curProcState,
11368 cpr.uid, cpr.name, cpr.info.processName);
11371 cpr.addExternalProcessHandleLocked(externalProcessToken);
11375 boolean decProviderCountLocked(ContentProviderConnection conn,
11376 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11377 if (conn != null) {
11378 cpr = conn.provider;
11379 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11380 "Removing provider requested by "
11381 + conn.client.processName + " from process "
11382 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11383 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11385 conn.stableCount--;
11387 conn.unstableCount--;
11389 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11390 cpr.connections.remove(conn);
11391 conn.client.conProviders.remove(conn);
11392 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11393 // The client is more important than last activity -- note the time this
11394 // is happening, so we keep the old provider process around a bit as last
11395 // activity to avoid thrashing it.
11396 if (cpr.proc != null) {
11397 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11400 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11405 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11409 private void checkTime(long startTime, String where) {
11410 long now = SystemClock.uptimeMillis();
11411 if ((now-startTime) > 50) {
11412 // If we are taking more than 50ms, log about it.
11413 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11417 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11419 PROC_SPACE_TERM|PROC_PARENS,
11420 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11423 private final long[] mProcessStateStatsLongs = new long[1];
11425 boolean isProcessAliveLocked(ProcessRecord proc) {
11426 if (proc.procStatFile == null) {
11427 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11429 mProcessStateStatsLongs[0] = 0;
11430 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11431 mProcessStateStatsLongs, null)) {
11432 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11435 final long state = mProcessStateStatsLongs[0];
11436 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11438 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11441 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11442 String name, IBinder token, boolean stable, int userId) {
11443 ContentProviderRecord cpr;
11444 ContentProviderConnection conn = null;
11445 ProviderInfo cpi = null;
11447 synchronized(this) {
11448 long startTime = SystemClock.uptimeMillis();
11450 ProcessRecord r = null;
11451 if (caller != null) {
11452 r = getRecordForAppLocked(caller);
11454 throw new SecurityException(
11455 "Unable to find app for caller " + caller
11456 + " (pid=" + Binder.getCallingPid()
11457 + ") when getting content provider " + name);
11461 boolean checkCrossUser = true;
11463 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11465 // First check if this content provider has been published...
11466 cpr = mProviderMap.getProviderByName(name, userId);
11467 // If that didn't work, check if it exists for user 0 and then
11468 // verify that it's a singleton provider before using it.
11469 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11470 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11473 if (isSingleton(cpi.processName, cpi.applicationInfo,
11474 cpi.name, cpi.flags)
11475 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11476 userId = UserHandle.USER_SYSTEM;
11477 checkCrossUser = false;
11485 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11486 if (providerRunning) {
11489 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11490 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11492 throw new SecurityException(msg);
11494 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11496 if (r != null && cpr.canRunHere(r)) {
11497 // This provider has been published or is in the process
11498 // of being published... but it is also allowed to run
11499 // in the caller's process, so don't make a connection
11500 // and just let the caller instantiate its own instance.
11501 ContentProviderHolder holder = cpr.newHolder(null);
11502 // don't give caller the provider object, it needs
11503 // to make its own.
11504 holder.provider = null;
11507 // Don't expose providers between normal apps and instant apps
11509 if (AppGlobals.getPackageManager()
11510 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11513 } catch (RemoteException e) {
11516 final long origId = Binder.clearCallingIdentity();
11518 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11520 // In this case the provider instance already exists, so we can
11521 // return it right away.
11522 conn = incProviderCountLocked(r, cpr, token, stable);
11523 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11524 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11525 // If this is a perceptible app accessing the provider,
11526 // make sure to count it as being accessed and thus
11527 // back up on the LRU list. This is good because
11528 // content providers are often expensive to start.
11529 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11530 updateLruProcessLocked(cpr.proc, false, null);
11531 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11535 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11536 final int verifiedAdj = cpr.proc.verifiedAdj;
11537 boolean success = updateOomAdjLocked(cpr.proc, true);
11538 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11539 // if the process has been successfully adjusted. So to reduce races with
11540 // it, we will check whether the process still exists. Note that this doesn't
11541 // completely get rid of races with LMK killing the process, but should make
11542 // them much smaller.
11543 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11546 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11547 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11548 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11549 // NOTE: there is still a race here where a signal could be
11550 // pending on the process even though we managed to update its
11551 // adj level. Not sure what to do about this, but at least
11552 // the race is now smaller.
11554 // Uh oh... it looks like the provider's process
11555 // has been killed on us. We need to wait for a new
11556 // process to be started, and make sure its death
11557 // doesn't kill our process.
11558 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11559 + " is crashing; detaching " + r);
11560 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11561 checkTime(startTime, "getContentProviderImpl: before appDied");
11562 appDiedLocked(cpr.proc);
11563 checkTime(startTime, "getContentProviderImpl: after appDied");
11565 // This wasn't the last ref our process had on
11566 // the provider... we have now been killed, bail.
11569 providerRunning = false;
11572 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11575 Binder.restoreCallingIdentity(origId);
11578 if (!providerRunning) {
11580 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11581 cpi = AppGlobals.getPackageManager().
11582 resolveContentProvider(name,
11583 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11584 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11585 } catch (RemoteException ex) {
11590 // If the provider is a singleton AND
11591 // (it's a call within the same user || the provider is a
11593 // Then allow connecting to the singleton provider
11594 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11595 cpi.name, cpi.flags)
11596 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11598 userId = UserHandle.USER_SYSTEM;
11600 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11601 checkTime(startTime, "getContentProviderImpl: got app info for user");
11604 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11605 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11607 throw new SecurityException(msg);
11609 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11611 if (!mProcessesReady
11612 && !cpi.processName.equals("system")) {
11613 // If this content provider does not run in the system
11614 // process, and the system is not yet ready to run other
11615 // processes, then fail fast instead of hanging.
11616 throw new IllegalArgumentException(
11617 "Attempt to launch content provider before system ready");
11620 // Make sure that the user who owns this provider is running. If not,
11621 // we don't want to allow it to run.
11622 if (!mUserController.isUserRunningLocked(userId, 0)) {
11623 Slog.w(TAG, "Unable to launch app "
11624 + cpi.applicationInfo.packageName + "/"
11625 + cpi.applicationInfo.uid + " for provider "
11626 + name + ": user " + userId + " is stopped");
11630 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11631 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11632 cpr = mProviderMap.getProviderByClass(comp, userId);
11633 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11634 final boolean firstClass = cpr == null;
11636 final long ident = Binder.clearCallingIdentity();
11638 // If permissions need a review before any of the app components can run,
11639 // we return no provider and launch a review activity if the calling app
11640 // is in the foreground.
11641 if (mPermissionReviewRequired) {
11642 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11648 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11649 ApplicationInfo ai =
11650 AppGlobals.getPackageManager().
11651 getApplicationInfo(
11652 cpi.applicationInfo.packageName,
11653 STOCK_PM_FLAGS, userId);
11654 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11656 Slog.w(TAG, "No package info for content provider "
11660 ai = getAppInfoForUser(ai, userId);
11661 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11662 } catch (RemoteException ex) {
11663 // pm is in same process, this will never happen.
11665 Binder.restoreCallingIdentity(ident);
11669 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11671 if (r != null && cpr.canRunHere(r)) {
11672 // If this is a multiprocess provider, then just return its
11673 // info and allow the caller to instantiate it. Only do
11674 // this if the provider is the same user as the caller's
11675 // process, or can run as root (so can be in any process).
11676 return cpr.newHolder(null);
11679 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11680 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11681 + cpr.info.name + " callers=" + Debug.getCallers(6));
11683 // This is single process, and our app is now connecting to it.
11684 // See if we are already in the process of launching this
11686 final int N = mLaunchingProviders.size();
11688 for (i = 0; i < N; i++) {
11689 if (mLaunchingProviders.get(i) == cpr) {
11694 // If the provider is not already being launched, then get it
11697 final long origId = Binder.clearCallingIdentity();
11700 // Content provider is now in use, its package can't be stopped.
11702 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11703 AppGlobals.getPackageManager().setPackageStoppedState(
11704 cpr.appInfo.packageName, false, userId);
11705 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11706 } catch (RemoteException e) {
11707 } catch (IllegalArgumentException e) {
11708 Slog.w(TAG, "Failed trying to unstop package "
11709 + cpr.appInfo.packageName + ": " + e);
11712 // Use existing process if already started
11713 checkTime(startTime, "getContentProviderImpl: looking for process record");
11714 ProcessRecord proc = getProcessRecordLocked(
11715 cpi.processName, cpr.appInfo.uid, false);
11716 if (proc != null && proc.thread != null && !proc.killed) {
11717 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11718 "Installing in existing process " + proc);
11719 if (!proc.pubProviders.containsKey(cpi.name)) {
11720 checkTime(startTime, "getContentProviderImpl: scheduling install");
11721 proc.pubProviders.put(cpi.name, cpr);
11723 proc.thread.scheduleInstallProvider(cpi);
11724 } catch (RemoteException e) {
11728 checkTime(startTime, "getContentProviderImpl: before start process");
11729 proc = startProcessLocked(cpi.processName,
11730 cpr.appInfo, false, 0, "content provider",
11731 new ComponentName(cpi.applicationInfo.packageName,
11732 cpi.name), false, false, false);
11733 checkTime(startTime, "getContentProviderImpl: after start process");
11734 if (proc == null) {
11735 Slog.w(TAG, "Unable to launch app "
11736 + cpi.applicationInfo.packageName + "/"
11737 + cpi.applicationInfo.uid + " for provider "
11738 + name + ": process is bad");
11742 cpr.launchingApp = proc;
11743 mLaunchingProviders.add(cpr);
11745 Binder.restoreCallingIdentity(origId);
11749 checkTime(startTime, "getContentProviderImpl: updating data structures");
11751 // Make sure the provider is published (the same provider class
11752 // may be published under multiple names).
11754 mProviderMap.putProviderByClass(comp, cpr);
11757 mProviderMap.putProviderByName(name, cpr);
11758 conn = incProviderCountLocked(r, cpr, token, stable);
11759 if (conn != null) {
11760 conn.waiting = true;
11763 checkTime(startTime, "getContentProviderImpl: done!");
11765 grantEphemeralAccessLocked(userId, null /*intent*/,
11766 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11769 // Wait for the provider to be published...
11770 synchronized (cpr) {
11771 while (cpr.provider == null) {
11772 if (cpr.launchingApp == null) {
11773 Slog.w(TAG, "Unable to launch app "
11774 + cpi.applicationInfo.packageName + "/"
11775 + cpi.applicationInfo.uid + " for provider "
11776 + name + ": launching app became null");
11777 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11778 UserHandle.getUserId(cpi.applicationInfo.uid),
11779 cpi.applicationInfo.packageName,
11780 cpi.applicationInfo.uid, name);
11784 if (DEBUG_MU) Slog.v(TAG_MU,
11785 "Waiting to start provider " + cpr
11786 + " launchingApp=" + cpr.launchingApp);
11787 if (conn != null) {
11788 conn.waiting = true;
11791 } catch (InterruptedException ex) {
11793 if (conn != null) {
11794 conn.waiting = false;
11799 return cpr != null ? cpr.newHolder(conn) : null;
11802 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11803 ProcessRecord r, final int userId) {
11804 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11805 cpi.packageName, userId)) {
11807 final boolean callerForeground = r == null || r.setSchedGroup
11808 != ProcessList.SCHED_GROUP_BACKGROUND;
11810 // Show a permission review UI only for starting from a foreground app
11811 if (!callerForeground) {
11812 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11813 + cpi.packageName + " requires a permissions review");
11817 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11818 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11819 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11820 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11822 if (DEBUG_PERMISSIONS_REVIEW) {
11823 Slog.i(TAG, "u" + userId + " Launching permission review "
11824 + "for package " + cpi.packageName);
11827 final UserHandle userHandle = new UserHandle(userId);
11828 mHandler.post(new Runnable() {
11830 public void run() {
11831 mContext.startActivityAsUser(intent, userHandle);
11841 PackageManagerInternal getPackageManagerInternalLocked() {
11842 if (mPackageManagerInt == null) {
11843 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11845 return mPackageManagerInt;
11849 public final ContentProviderHolder getContentProvider(
11850 IApplicationThread caller, String name, int userId, boolean stable) {
11851 enforceNotIsolatedCaller("getContentProvider");
11852 if (caller == null) {
11853 String msg = "null IApplicationThread when getting content provider "
11856 throw new SecurityException(msg);
11858 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11859 // with cross-user grant.
11860 return getContentProviderImpl(caller, name, null, stable, userId);
11863 public ContentProviderHolder getContentProviderExternal(
11864 String name, int userId, IBinder token) {
11865 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11866 "Do not have permission in call getContentProviderExternal()");
11867 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11868 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11869 return getContentProviderExternalUnchecked(name, token, userId);
11872 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11873 IBinder token, int userId) {
11874 return getContentProviderImpl(null, name, token, true, userId);
11878 * Drop a content provider from a ProcessRecord's bookkeeping
11880 public void removeContentProvider(IBinder connection, boolean stable) {
11881 enforceNotIsolatedCaller("removeContentProvider");
11882 long ident = Binder.clearCallingIdentity();
11884 synchronized (this) {
11885 ContentProviderConnection conn;
11887 conn = (ContentProviderConnection)connection;
11888 } catch (ClassCastException e) {
11889 String msg ="removeContentProvider: " + connection
11890 + " not a ContentProviderConnection";
11892 throw new IllegalArgumentException(msg);
11894 if (conn == null) {
11895 throw new NullPointerException("connection is null");
11897 if (decProviderCountLocked(conn, null, null, stable)) {
11898 updateOomAdjLocked();
11902 Binder.restoreCallingIdentity(ident);
11906 public void removeContentProviderExternal(String name, IBinder token) {
11907 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11908 "Do not have permission in call removeContentProviderExternal()");
11909 int userId = UserHandle.getCallingUserId();
11910 long ident = Binder.clearCallingIdentity();
11912 removeContentProviderExternalUnchecked(name, token, userId);
11914 Binder.restoreCallingIdentity(ident);
11918 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11919 synchronized (this) {
11920 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11922 //remove from mProvidersByClass
11923 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11927 //update content provider record entry info
11928 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11929 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11930 if (localCpr.hasExternalProcessHandles()) {
11931 if (localCpr.removeExternalProcessHandleLocked(token)) {
11932 updateOomAdjLocked();
11934 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11935 + " with no external reference for token: "
11939 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11940 + " with no external references.");
11945 public final void publishContentProviders(IApplicationThread caller,
11946 List<ContentProviderHolder> providers) {
11947 if (providers == null) {
11951 enforceNotIsolatedCaller("publishContentProviders");
11952 synchronized (this) {
11953 final ProcessRecord r = getRecordForAppLocked(caller);
11954 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11956 throw new SecurityException(
11957 "Unable to find app for caller " + caller
11958 + " (pid=" + Binder.getCallingPid()
11959 + ") when publishing content providers");
11962 final long origId = Binder.clearCallingIdentity();
11964 final int N = providers.size();
11965 for (int i = 0; i < N; i++) {
11966 ContentProviderHolder src = providers.get(i);
11967 if (src == null || src.info == null || src.provider == null) {
11970 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11971 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11973 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11974 mProviderMap.putProviderByClass(comp, dst);
11975 String names[] = dst.info.authority.split(";");
11976 for (int j = 0; j < names.length; j++) {
11977 mProviderMap.putProviderByName(names[j], dst);
11980 int launchingCount = mLaunchingProviders.size();
11982 boolean wasInLaunchingProviders = false;
11983 for (j = 0; j < launchingCount; j++) {
11984 if (mLaunchingProviders.get(j) == dst) {
11985 mLaunchingProviders.remove(j);
11986 wasInLaunchingProviders = true;
11991 if (wasInLaunchingProviders) {
11992 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11994 synchronized (dst) {
11995 dst.provider = src.provider;
11999 updateOomAdjLocked(r, true);
12000 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12001 src.info.authority);
12005 Binder.restoreCallingIdentity(origId);
12009 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12010 ContentProviderConnection conn;
12012 conn = (ContentProviderConnection)connection;
12013 } catch (ClassCastException e) {
12014 String msg ="refContentProvider: " + connection
12015 + " not a ContentProviderConnection";
12017 throw new IllegalArgumentException(msg);
12019 if (conn == null) {
12020 throw new NullPointerException("connection is null");
12023 synchronized (this) {
12025 conn.numStableIncs += stable;
12027 stable = conn.stableCount + stable;
12029 throw new IllegalStateException("stableCount < 0: " + stable);
12032 if (unstable > 0) {
12033 conn.numUnstableIncs += unstable;
12035 unstable = conn.unstableCount + unstable;
12036 if (unstable < 0) {
12037 throw new IllegalStateException("unstableCount < 0: " + unstable);
12040 if ((stable+unstable) <= 0) {
12041 throw new IllegalStateException("ref counts can't go to zero here: stable="
12042 + stable + " unstable=" + unstable);
12044 conn.stableCount = stable;
12045 conn.unstableCount = unstable;
12050 public void unstableProviderDied(IBinder connection) {
12051 ContentProviderConnection conn;
12053 conn = (ContentProviderConnection)connection;
12054 } catch (ClassCastException e) {
12055 String msg ="refContentProvider: " + connection
12056 + " not a ContentProviderConnection";
12058 throw new IllegalArgumentException(msg);
12060 if (conn == null) {
12061 throw new NullPointerException("connection is null");
12064 // Safely retrieve the content provider associated with the connection.
12065 IContentProvider provider;
12066 synchronized (this) {
12067 provider = conn.provider.provider;
12070 if (provider == null) {
12071 // Um, yeah, we're way ahead of you.
12075 // Make sure the caller is being honest with us.
12076 if (provider.asBinder().pingBinder()) {
12077 // Er, no, still looks good to us.
12078 synchronized (this) {
12079 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12080 + " says " + conn + " died, but we don't agree");
12085 // Well look at that! It's dead!
12086 synchronized (this) {
12087 if (conn.provider.provider != provider) {
12088 // But something changed... good enough.
12092 ProcessRecord proc = conn.provider.proc;
12093 if (proc == null || proc.thread == null) {
12094 // Seems like the process is already cleaned up.
12098 // As far as we're concerned, this is just like receiving a
12099 // death notification... just a bit prematurely.
12100 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12101 + ") early provider death");
12102 final long ident = Binder.clearCallingIdentity();
12104 appDiedLocked(proc);
12106 Binder.restoreCallingIdentity(ident);
12112 public void appNotRespondingViaProvider(IBinder connection) {
12113 enforceCallingPermission(
12114 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12116 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12117 if (conn == null) {
12118 Slog.w(TAG, "ContentProviderConnection is null");
12122 final ProcessRecord host = conn.provider.proc;
12123 if (host == null) {
12124 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12128 mHandler.post(new Runnable() {
12130 public void run() {
12131 mAppErrors.appNotResponding(host, null, null, false,
12132 "ContentProvider not responding");
12137 public final void installSystemProviders() {
12138 List<ProviderInfo> providers;
12139 synchronized (this) {
12140 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12141 providers = generateApplicationProvidersLocked(app);
12142 if (providers != null) {
12143 for (int i=providers.size()-1; i>=0; i--) {
12144 ProviderInfo pi = (ProviderInfo)providers.get(i);
12145 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12146 Slog.w(TAG, "Not installing system proc provider " + pi.name
12147 + ": not system .apk");
12148 providers.remove(i);
12153 if (providers != null) {
12154 mSystemThread.installSystemProviders(providers);
12157 mConstants.start(mContext.getContentResolver());
12158 mCoreSettingsObserver = new CoreSettingsObserver(this);
12159 mFontScaleSettingObserver = new FontScaleSettingObserver();
12161 // Now that the settings provider is published we can consider sending
12162 // in a rescue party.
12163 RescueParty.onSettingsProviderPublished(mContext);
12165 //mUsageStatsService.monitorPackages();
12168 private void startPersistentApps(int matchFlags) {
12169 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12171 synchronized (this) {
12173 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12174 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12175 for (ApplicationInfo app : apps) {
12176 if (!"android".equals(app.packageName)) {
12177 addAppLocked(app, null, false, null /* ABI override */);
12180 } catch (RemoteException ex) {
12186 * When a user is unlocked, we need to install encryption-unaware providers
12187 * belonging to any running apps.
12189 private void installEncryptionUnawareProviders(int userId) {
12190 // We're only interested in providers that are encryption unaware, and
12191 // we don't care about uninstalled apps, since there's no way they're
12192 // running at this point.
12193 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12195 synchronized (this) {
12196 final int NP = mProcessNames.getMap().size();
12197 for (int ip = 0; ip < NP; ip++) {
12198 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12199 final int NA = apps.size();
12200 for (int ia = 0; ia < NA; ia++) {
12201 final ProcessRecord app = apps.valueAt(ia);
12202 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12204 final int NG = app.pkgList.size();
12205 for (int ig = 0; ig < NG; ig++) {
12207 final String pkgName = app.pkgList.keyAt(ig);
12208 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12209 .getPackageInfo(pkgName, matchFlags, userId);
12210 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12211 for (ProviderInfo pi : pkgInfo.providers) {
12212 // TODO: keep in sync with generateApplicationProvidersLocked
12213 final boolean processMatch = Objects.equals(pi.processName,
12214 app.processName) || pi.multiprocess;
12215 final boolean userMatch = isSingleton(pi.processName,
12216 pi.applicationInfo, pi.name, pi.flags)
12217 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12218 if (processMatch && userMatch) {
12219 Log.v(TAG, "Installing " + pi);
12220 app.thread.scheduleInstallProvider(pi);
12222 Log.v(TAG, "Skipping " + pi);
12226 } catch (RemoteException ignored) {
12235 * Allows apps to retrieve the MIME type of a URI.
12236 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12237 * users, then it does not need permission to access the ContentProvider.
12238 * Either, it needs cross-user uri grants.
12240 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12242 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12243 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12245 public String getProviderMimeType(Uri uri, int userId) {
12246 enforceNotIsolatedCaller("getProviderMimeType");
12247 final String name = uri.getAuthority();
12248 int callingUid = Binder.getCallingUid();
12249 int callingPid = Binder.getCallingPid();
12251 boolean clearedIdentity = false;
12252 synchronized (this) {
12253 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12255 if (canClearIdentity(callingPid, callingUid, userId)) {
12256 clearedIdentity = true;
12257 ident = Binder.clearCallingIdentity();
12259 ContentProviderHolder holder = null;
12261 holder = getContentProviderExternalUnchecked(name, null, userId);
12262 if (holder != null) {
12263 return holder.provider.getType(uri);
12265 } catch (RemoteException e) {
12266 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12268 } catch (Exception e) {
12269 Log.w(TAG, "Exception while determining type of " + uri, e);
12272 // We need to clear the identity to call removeContentProviderExternalUnchecked
12273 if (!clearedIdentity) {
12274 ident = Binder.clearCallingIdentity();
12277 if (holder != null) {
12278 removeContentProviderExternalUnchecked(name, null, userId);
12281 Binder.restoreCallingIdentity(ident);
12288 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12289 if (UserHandle.getUserId(callingUid) == userId) {
12292 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12293 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12294 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12295 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12301 // =========================================================
12302 // GLOBAL MANAGEMENT
12303 // =========================================================
12305 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12306 boolean isolated, int isolatedUid) {
12307 String proc = customProcess != null ? customProcess : info.processName;
12308 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12309 final int userId = UserHandle.getUserId(info.uid);
12310 int uid = info.uid;
12312 if (isolatedUid == 0) {
12313 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12315 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12316 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12317 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12319 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12320 mNextIsolatedProcessUid++;
12321 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12322 // No process for this uid, use it.
12326 if (stepsLeft <= 0) {
12331 // Special case for startIsolatedProcess (internal only), where
12332 // the uid of the isolated process is specified by the caller.
12335 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12337 // Register the isolated UID with this application so BatteryStats knows to
12338 // attribute resource usage to the application.
12340 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12341 // about the process state of the isolated UID *before* it is registered with the
12342 // owning application.
12343 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12345 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12346 if (!mBooted && !mBooting
12347 && userId == UserHandle.USER_SYSTEM
12348 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12349 r.persistent = true;
12350 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12352 addProcessNameLocked(r);
12356 private boolean uidOnBackgroundWhitelist(final int uid) {
12357 final int appId = UserHandle.getAppId(uid);
12358 final int[] whitelist = mBackgroundAppIdWhitelist;
12359 final int N = whitelist.length;
12360 for (int i = 0; i < N; i++) {
12361 if (appId == whitelist[i]) {
12369 public void backgroundWhitelistUid(final int uid) {
12370 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12371 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12374 if (DEBUG_BACKGROUND_CHECK) {
12375 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12377 synchronized (this) {
12378 final int N = mBackgroundAppIdWhitelist.length;
12379 int[] newList = new int[N+1];
12380 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12381 newList[N] = UserHandle.getAppId(uid);
12382 mBackgroundAppIdWhitelist = newList;
12386 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12387 String abiOverride) {
12390 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12397 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12398 updateLruProcessLocked(app, false, null);
12399 updateOomAdjLocked();
12402 // This package really, really can not be stopped.
12404 AppGlobals.getPackageManager().setPackageStoppedState(
12405 info.packageName, false, UserHandle.getUserId(app.uid));
12406 } catch (RemoteException e) {
12407 } catch (IllegalArgumentException e) {
12408 Slog.w(TAG, "Failed trying to unstop package "
12409 + info.packageName + ": " + e);
12412 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12413 app.persistent = true;
12414 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12416 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12417 mPersistentStartingProcesses.add(app);
12418 startProcessLocked(app, "added application",
12419 customProcess != null ? customProcess : app.processName, abiOverride,
12420 null /* entryPoint */, null /* entryPointArgs */);
12426 public void unhandledBack() {
12427 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12428 "unhandledBack()");
12430 synchronized(this) {
12431 final long origId = Binder.clearCallingIdentity();
12433 getFocusedStack().unhandledBackLocked();
12435 Binder.restoreCallingIdentity(origId);
12440 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12441 enforceNotIsolatedCaller("openContentUri");
12442 final int userId = UserHandle.getCallingUserId();
12443 final Uri uri = Uri.parse(uriString);
12444 String name = uri.getAuthority();
12445 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12446 ParcelFileDescriptor pfd = null;
12448 // We record the binder invoker's uid in thread-local storage before
12449 // going to the content provider to open the file. Later, in the code
12450 // that handles all permissions checks, we look for this uid and use
12451 // that rather than the Activity Manager's own uid. The effect is that
12452 // we do the check against the caller's permissions even though it looks
12453 // to the content provider like the Activity Manager itself is making
12455 Binder token = new Binder();
12456 sCallerIdentity.set(new Identity(
12457 token, Binder.getCallingPid(), Binder.getCallingUid()));
12459 pfd = cph.provider.openFile(null, uri, "r", null, token);
12460 } catch (FileNotFoundException e) {
12461 // do nothing; pfd will be returned null
12463 // Ensure that whatever happens, we clean up the identity state
12464 sCallerIdentity.remove();
12465 // Ensure we're done with the provider.
12466 removeContentProviderExternalUnchecked(name, null, userId);
12469 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12474 // Actually is sleeping or shutting down or whatever else in the future
12475 // is an inactive state.
12476 boolean isSleepingOrShuttingDownLocked() {
12477 return isSleepingLocked() || mShuttingDown;
12480 boolean isShuttingDownLocked() {
12481 return mShuttingDown;
12484 boolean isSleepingLocked() {
12488 void onWakefulnessChanged(int wakefulness) {
12489 synchronized(this) {
12490 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12491 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12492 mWakefulness = wakefulness;
12494 if (wasAwake != isAwake) {
12495 // Also update state in a special way for running foreground services UI.
12496 mServices.updateScreenStateLocked(isAwake);
12497 sendNotifyVrManagerOfSleepState(!isAwake);
12502 void finishRunningVoiceLocked() {
12503 if (mRunningVoice != null) {
12504 mRunningVoice = null;
12505 mVoiceWakeLock.release();
12506 updateSleepIfNeededLocked();
12510 void startTimeTrackingFocusedActivityLocked() {
12511 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12512 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12513 mCurAppTimeTracker.start(resumedActivity.packageName);
12517 void updateSleepIfNeededLocked() {
12518 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12519 final boolean wasSleeping = mSleeping;
12521 if (!shouldSleep) {
12522 // If wasSleeping is true, we need to wake up activity manager state from when
12523 // we started sleeping. In either case, we need to apply the sleep tokens, which
12524 // will wake up stacks or put them to sleep as appropriate.
12527 startTimeTrackingFocusedActivityLocked();
12528 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12529 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12531 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12533 updateOomAdjLocked();
12535 } else if (!mSleeping && shouldSleep) {
12537 if (mCurAppTimeTracker != null) {
12538 mCurAppTimeTracker.stop();
12540 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12541 mStackSupervisor.goingToSleepLocked();
12542 updateOomAdjLocked();
12546 /** Pokes the task persister. */
12547 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12548 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12552 * Notifies all listeners when the pinned stack animation starts.
12555 public void notifyPinnedStackAnimationStarted() {
12556 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12560 * Notifies all listeners when the pinned stack animation ends.
12563 public void notifyPinnedStackAnimationEnded() {
12564 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12568 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12569 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12573 public boolean shutdown(int timeout) {
12574 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12575 != PackageManager.PERMISSION_GRANTED) {
12576 throw new SecurityException("Requires permission "
12577 + android.Manifest.permission.SHUTDOWN);
12580 boolean timedout = false;
12582 synchronized(this) {
12583 mShuttingDown = true;
12584 mStackSupervisor.prepareForShutdownLocked();
12585 updateEventDispatchingLocked();
12586 timedout = mStackSupervisor.shutdownLocked(timeout);
12589 mAppOpsService.shutdown();
12590 if (mUsageStatsService != null) {
12591 mUsageStatsService.prepareShutdown();
12593 mBatteryStatsService.shutdown();
12594 synchronized (this) {
12595 mProcessStats.shutdownLocked();
12596 notifyTaskPersisterLocked(null, true);
12602 public final void activitySlept(IBinder token) {
12603 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12605 final long origId = Binder.clearCallingIdentity();
12607 synchronized (this) {
12608 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12610 mStackSupervisor.activitySleptLocked(r);
12614 Binder.restoreCallingIdentity(origId);
12617 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12618 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12619 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12620 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12621 boolean wasRunningVoice = mRunningVoice != null;
12622 mRunningVoice = session;
12623 if (!wasRunningVoice) {
12624 mVoiceWakeLock.acquire();
12625 updateSleepIfNeededLocked();
12630 private void updateEventDispatchingLocked() {
12631 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12635 public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12636 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12637 != PackageManager.PERMISSION_GRANTED) {
12638 throw new SecurityException("Requires permission "
12639 + android.Manifest.permission.DEVICE_POWER);
12642 synchronized(this) {
12643 long ident = Binder.clearCallingIdentity();
12645 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12647 Binder.restoreCallingIdentity(ident);
12650 sendNotifyVrManagerOfKeyguardState(showing);
12654 public void notifyLockedProfile(@UserIdInt int userId) {
12656 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12657 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12659 } catch (RemoteException ex) {
12660 throw new SecurityException("Fail to check is caller a privileged app", ex);
12663 synchronized (this) {
12664 final long ident = Binder.clearCallingIdentity();
12666 if (mUserController.shouldConfirmCredentials(userId)) {
12667 if (mKeyguardController.isKeyguardLocked()) {
12668 // Showing launcher to avoid user entering credential twice.
12669 final int currentUserId = mUserController.getCurrentUserIdLocked();
12670 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12672 mStackSupervisor.lockAllProfileTasks(userId);
12675 Binder.restoreCallingIdentity(ident);
12681 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12682 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12683 synchronized (this) {
12684 final long ident = Binder.clearCallingIdentity();
12686 mActivityStarter.startConfirmCredentialIntent(intent, options);
12688 Binder.restoreCallingIdentity(ident);
12694 public void stopAppSwitches() {
12695 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12696 != PackageManager.PERMISSION_GRANTED) {
12697 throw new SecurityException("viewquires permission "
12698 + android.Manifest.permission.STOP_APP_SWITCHES);
12701 synchronized(this) {
12702 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12703 + APP_SWITCH_DELAY_TIME;
12704 mDidAppSwitch = false;
12705 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12706 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12707 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12711 public void resumeAppSwitches() {
12712 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12713 != PackageManager.PERMISSION_GRANTED) {
12714 throw new SecurityException("Requires permission "
12715 + android.Manifest.permission.STOP_APP_SWITCHES);
12718 synchronized(this) {
12719 // Note that we don't execute any pending app switches... we will
12720 // let those wait until either the timeout, or the next start
12721 // activity request.
12722 mAppSwitchesAllowedTime = 0;
12726 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12727 int callingPid, int callingUid, String name) {
12728 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12732 int perm = checkComponentPermission(
12733 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12734 sourceUid, -1, true);
12735 if (perm == PackageManager.PERMISSION_GRANTED) {
12739 // If the actual IPC caller is different from the logical source, then
12740 // also see if they are allowed to control app switches.
12741 if (callingUid != -1 && callingUid != sourceUid) {
12742 perm = checkComponentPermission(
12743 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12744 callingUid, -1, true);
12745 if (perm == PackageManager.PERMISSION_GRANTED) {
12750 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12754 public void setDebugApp(String packageName, boolean waitForDebugger,
12755 boolean persistent) {
12756 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12759 long ident = Binder.clearCallingIdentity();
12761 // Note that this is not really thread safe if there are multiple
12762 // callers into it at the same time, but that's not a situation we
12765 final ContentResolver resolver = mContext.getContentResolver();
12766 Settings.Global.putString(
12767 resolver, Settings.Global.DEBUG_APP,
12769 Settings.Global.putInt(
12770 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12771 waitForDebugger ? 1 : 0);
12774 synchronized (this) {
12776 mOrigDebugApp = mDebugApp;
12777 mOrigWaitForDebugger = mWaitForDebugger;
12779 mDebugApp = packageName;
12780 mWaitForDebugger = waitForDebugger;
12781 mDebugTransient = !persistent;
12782 if (packageName != null) {
12783 forceStopPackageLocked(packageName, -1, false, false, true, true,
12784 false, UserHandle.USER_ALL, "set debug app");
12788 Binder.restoreCallingIdentity(ident);
12792 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12793 synchronized (this) {
12794 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12795 if (!isDebuggable) {
12796 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12797 throw new SecurityException("Process not debuggable: " + app.packageName);
12801 mTrackAllocationApp = processName;
12805 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12806 synchronized (this) {
12807 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12808 if (!isDebuggable) {
12809 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12810 throw new SecurityException("Process not debuggable: " + app.packageName);
12813 mProfileApp = processName;
12815 if (mProfilerInfo != null) {
12816 if (mProfilerInfo.profileFd != null) {
12818 mProfilerInfo.profileFd.close();
12819 } catch (IOException e) {
12823 mProfilerInfo = new ProfilerInfo(profilerInfo);
12828 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12829 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12830 if (!isDebuggable) {
12831 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12832 throw new SecurityException("Process not debuggable: " + app.packageName);
12835 mNativeDebuggingApp = processName;
12839 public void setAlwaysFinish(boolean enabled) {
12840 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12841 "setAlwaysFinish()");
12843 long ident = Binder.clearCallingIdentity();
12845 Settings.Global.putInt(
12846 mContext.getContentResolver(),
12847 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12849 synchronized (this) {
12850 mAlwaysFinishActivities = enabled;
12853 Binder.restoreCallingIdentity(ident);
12858 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12859 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12860 "setActivityController()");
12861 synchronized (this) {
12862 mController = controller;
12863 mControllerIsAMonkey = imAMonkey;
12864 Watchdog.getInstance().setActivityController(controller);
12869 public void setUserIsMonkey(boolean userIsMonkey) {
12870 synchronized (this) {
12871 synchronized (mPidsSelfLocked) {
12872 final int callingPid = Binder.getCallingPid();
12873 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12874 if (proc == null) {
12875 throw new SecurityException("Unknown process: " + callingPid);
12877 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12878 throw new SecurityException("Only an instrumentation process "
12879 + "with a UiAutomation can call setUserIsMonkey");
12882 mUserIsMonkey = userIsMonkey;
12887 public boolean isUserAMonkey() {
12888 synchronized (this) {
12889 // If there is a controller also implies the user is a monkey.
12890 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12895 * @deprecated This method is only used by a few internal components and it will soon be
12896 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12897 * No new code should be calling it.
12901 public void requestBugReport(int bugreportType) {
12902 String extraOptions = null;
12903 switch (bugreportType) {
12904 case ActivityManager.BUGREPORT_OPTION_FULL:
12905 // Default options.
12907 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12908 extraOptions = "bugreportplus";
12910 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12911 extraOptions = "bugreportremote";
12913 case ActivityManager.BUGREPORT_OPTION_WEAR:
12914 extraOptions = "bugreportwear";
12916 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12917 extraOptions = "bugreporttelephony";
12920 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12923 // Always log caller, even if it does not have permission to dump.
12924 String type = extraOptions == null ? "bugreport" : extraOptions;
12925 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12927 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12928 if (extraOptions != null) {
12929 SystemProperties.set("dumpstate.options", extraOptions);
12931 SystemProperties.set("ctl.start", "bugreport");
12935 * @deprecated This method is only used by a few internal components and it will soon be
12936 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12937 * No new code should be calling it.
12941 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12943 if (!TextUtils.isEmpty(shareTitle)) {
12944 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12945 String errorStr = "shareTitle should be less than " +
12946 MAX_BUGREPORT_TITLE_SIZE + " characters";
12947 throw new IllegalArgumentException(errorStr);
12949 if (!TextUtils.isEmpty(shareDescription)) {
12952 length = shareDescription.getBytes("UTF-8").length;
12953 } catch (UnsupportedEncodingException e) {
12954 String errorStr = "shareDescription: UnsupportedEncodingException";
12955 throw new IllegalArgumentException(errorStr);
12957 if (length > SystemProperties.PROP_VALUE_MAX) {
12958 String errorStr = "shareTitle should be less than " +
12959 SystemProperties.PROP_VALUE_MAX + " bytes";
12960 throw new IllegalArgumentException(errorStr);
12962 SystemProperties.set("dumpstate.options.description", shareDescription);
12965 SystemProperties.set("dumpstate.options.title", shareTitle);
12969 Slog.d(TAG, "Bugreport notification title " + shareTitle
12970 + " description " + shareDescription);
12971 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12974 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12975 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12978 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12979 if (r != null && (r.instr != null || r.usingWrapper)) {
12980 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12982 return KEY_DISPATCHING_TIMEOUT;
12986 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12987 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12988 != PackageManager.PERMISSION_GRANTED) {
12989 throw new SecurityException("Requires permission "
12990 + android.Manifest.permission.FILTER_EVENTS);
12992 ProcessRecord proc;
12994 synchronized (this) {
12995 synchronized (mPidsSelfLocked) {
12996 proc = mPidsSelfLocked.get(pid);
12998 timeout = getInputDispatchingTimeoutLocked(proc);
13001 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13009 * Handle input dispatching timeouts.
13010 * Returns whether input dispatching should be aborted or not.
13012 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13013 final ActivityRecord activity, final ActivityRecord parent,
13014 final boolean aboveSystem, String reason) {
13015 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13016 != PackageManager.PERMISSION_GRANTED) {
13017 throw new SecurityException("Requires permission "
13018 + android.Manifest.permission.FILTER_EVENTS);
13021 final String annotation;
13022 if (reason == null) {
13023 annotation = "Input dispatching timed out";
13025 annotation = "Input dispatching timed out (" + reason + ")";
13028 if (proc != null) {
13029 synchronized (this) {
13030 if (proc.debugging) {
13034 if (proc.instr != null) {
13035 Bundle info = new Bundle();
13036 info.putString("shortMsg", "keyDispatchingTimedOut");
13037 info.putString("longMsg", annotation);
13038 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13042 mHandler.post(new Runnable() {
13044 public void run() {
13045 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13054 public Bundle getAssistContextExtras(int requestType) {
13055 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13056 null, null, true /* focused */, true /* newSessionId */,
13057 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13061 synchronized (pae) {
13062 while (!pae.haveResult) {
13065 } catch (InterruptedException e) {
13069 synchronized (this) {
13070 buildAssistBundleLocked(pae, pae.result);
13071 mPendingAssistExtras.remove(pae);
13072 mUiHandler.removeCallbacks(pae);
13078 public boolean isAssistDataAllowedOnCurrentActivity() {
13080 synchronized (this) {
13081 final ActivityStack focusedStack = getFocusedStack();
13082 if (focusedStack == null || focusedStack.isAssistantStack()) {
13086 final ActivityRecord activity = focusedStack.topActivity();
13087 if (activity == null) {
13090 userId = activity.userId;
13092 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13093 Context.DEVICE_POLICY_SERVICE);
13094 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13098 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13099 long ident = Binder.clearCallingIdentity();
13101 synchronized (this) {
13102 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13103 ActivityRecord top = getFocusedStack().topActivity();
13104 if (top != caller) {
13105 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13106 + " is not current top " + top);
13109 if (!top.nowVisible) {
13110 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13111 + " is not visible");
13115 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13118 Binder.restoreCallingIdentity(ident);
13123 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13124 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13125 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13126 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13127 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13131 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13132 IBinder activityToken, int flags) {
13133 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13134 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13135 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13138 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13139 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13140 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13142 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13143 "enqueueAssistContext()");
13145 synchronized (this) {
13146 ActivityRecord activity = getFocusedStack().topActivity();
13147 if (activity == null) {
13148 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13151 if (activity.app == null || activity.app.thread == null) {
13152 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13156 if (activityToken != null) {
13157 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13158 if (activity != caller) {
13159 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13160 + " is not current top " + activity);
13165 activity = ActivityRecord.forTokenLocked(activityToken);
13166 if (activity == null) {
13167 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13168 + " couldn't be found");
13171 if (activity.app == null || activity.app.thread == null) {
13172 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13177 PendingAssistExtras pae;
13178 Bundle extras = new Bundle();
13179 if (args != null) {
13180 extras.putAll(args);
13182 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13183 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13185 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13187 pae.isHome = activity.isHomeActivity();
13189 // Increment the sessionId if necessary
13190 if (newSessionId) {
13194 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13195 mViSessionId, flags);
13196 mPendingAssistExtras.add(pae);
13197 mUiHandler.postDelayed(pae, timeout);
13198 } catch (RemoteException e) {
13199 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13206 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13207 IResultReceiver receiver;
13208 synchronized (this) {
13209 mPendingAssistExtras.remove(pae);
13210 receiver = pae.receiver;
13212 if (receiver != null) {
13213 // Caller wants result sent back to them.
13214 Bundle sendBundle = new Bundle();
13215 // At least return the receiver extras
13216 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13217 pae.receiverExtras);
13219 pae.receiver.send(0, sendBundle);
13220 } catch (RemoteException e) {
13225 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13226 if (result != null) {
13227 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13229 if (pae.hint != null) {
13230 pae.extras.putBoolean(pae.hint, true);
13234 /** Called from an app when assist data is ready. */
13236 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13237 AssistContent content, Uri referrer) {
13238 PendingAssistExtras pae = (PendingAssistExtras)token;
13239 synchronized (pae) {
13240 pae.result = extras;
13241 pae.structure = structure;
13242 pae.content = content;
13243 if (referrer != null) {
13244 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13246 if (structure != null) {
13247 structure.setHomeActivity(pae.isHome);
13249 pae.haveResult = true;
13251 if (pae.intent == null && pae.receiver == null) {
13252 // Caller is just waiting for the result.
13256 // We are now ready to launch the assist activity.
13257 IResultReceiver sendReceiver = null;
13258 Bundle sendBundle = null;
13259 synchronized (this) {
13260 buildAssistBundleLocked(pae, extras);
13261 boolean exists = mPendingAssistExtras.remove(pae);
13262 mUiHandler.removeCallbacks(pae);
13267 if ((sendReceiver=pae.receiver) != null) {
13268 // Caller wants result sent back to them.
13269 sendBundle = new Bundle();
13270 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13271 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13272 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13273 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13274 pae.receiverExtras);
13277 if (sendReceiver != null) {
13279 sendReceiver.send(0, sendBundle);
13280 } catch (RemoteException e) {
13285 final long ident = Binder.clearCallingIdentity();
13287 if (TextUtils.equals(pae.intent.getAction(),
13288 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13289 pae.intent.putExtras(pae.extras);
13290 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13292 pae.intent.replaceExtras(pae.extras);
13293 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13294 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13295 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13296 closeSystemDialogs("assist");
13299 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13300 } catch (ActivityNotFoundException e) {
13301 Slog.w(TAG, "No activity to handle assist action.", e);
13305 Binder.restoreCallingIdentity(ident);
13309 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13311 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13312 true /* focused */, true /* newSessionId */, userHandle, args,
13313 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13316 public void registerProcessObserver(IProcessObserver observer) {
13317 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13318 "registerProcessObserver()");
13319 synchronized (this) {
13320 mProcessObservers.register(observer);
13325 public void unregisterProcessObserver(IProcessObserver observer) {
13326 synchronized (this) {
13327 mProcessObservers.unregister(observer);
13332 public int getUidProcessState(int uid, String callingPackage) {
13333 if (!hasUsageStatsPermission(callingPackage)) {
13334 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13335 "getUidProcessState");
13338 synchronized (this) {
13339 UidRecord uidRec = mActiveUids.get(uid);
13340 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13345 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13346 String callingPackage) {
13347 if (!hasUsageStatsPermission(callingPackage)) {
13348 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13349 "registerUidObserver");
13351 synchronized (this) {
13352 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13353 callingPackage, which, cutpoint));
13358 public void unregisterUidObserver(IUidObserver observer) {
13359 synchronized (this) {
13360 mUidObservers.unregister(observer);
13365 public boolean convertFromTranslucent(IBinder token) {
13366 final long origId = Binder.clearCallingIdentity();
13368 synchronized (this) {
13369 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13373 final boolean translucentChanged = r.changeWindowTranslucency(true);
13374 if (translucentChanged) {
13375 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13377 mWindowManager.setAppFullscreen(token, true);
13378 return translucentChanged;
13381 Binder.restoreCallingIdentity(origId);
13386 public boolean convertToTranslucent(IBinder token, Bundle options) {
13387 final long origId = Binder.clearCallingIdentity();
13389 synchronized (this) {
13390 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13394 final TaskRecord task = r.getTask();
13395 int index = task.mActivities.lastIndexOf(r);
13397 ActivityRecord under = task.mActivities.get(index - 1);
13398 under.returningOptions = ActivityOptions.fromBundle(options);
13400 final boolean translucentChanged = r.changeWindowTranslucency(false);
13401 if (translucentChanged) {
13402 r.getStack().convertActivityToTranslucent(r);
13404 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13405 mWindowManager.setAppFullscreen(token, false);
13406 return translucentChanged;
13409 Binder.restoreCallingIdentity(origId);
13414 public Bundle getActivityOptions(IBinder token) {
13415 final long origId = Binder.clearCallingIdentity();
13417 synchronized (this) {
13418 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13420 final ActivityOptions activityOptions = r.takeOptionsLocked();
13421 return activityOptions == null ? null : activityOptions.toBundle();
13426 Binder.restoreCallingIdentity(origId);
13431 public void setImmersive(IBinder token, boolean immersive) {
13432 synchronized(this) {
13433 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13435 throw new IllegalArgumentException();
13437 r.immersive = immersive;
13439 // update associated state if we're frontmost
13440 if (r == mStackSupervisor.getResumedActivityLocked()) {
13441 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13442 applyUpdateLockStateLocked(r);
13448 public boolean isImmersive(IBinder token) {
13449 synchronized (this) {
13450 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13452 throw new IllegalArgumentException();
13454 return r.immersive;
13459 public void setVrThread(int tid) {
13460 enforceSystemHasVrFeature();
13461 synchronized (this) {
13462 synchronized (mPidsSelfLocked) {
13463 final int pid = Binder.getCallingPid();
13464 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13465 mVrController.setVrThreadLocked(tid, pid, proc);
13471 public void setPersistentVrThread(int tid) {
13472 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13473 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13474 + Binder.getCallingPid()
13475 + ", uid=" + Binder.getCallingUid()
13476 + " requires " + permission.RESTRICTED_VR_ACCESS;
13478 throw new SecurityException(msg);
13480 enforceSystemHasVrFeature();
13481 synchronized (this) {
13482 synchronized (mPidsSelfLocked) {
13483 final int pid = Binder.getCallingPid();
13484 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13485 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13491 * Schedule the given thread a normal scheduling priority.
13493 * @param tid the tid of the thread to adjust the scheduling of.
13494 * @param suppressLogs {@code true} if any error logging should be disabled.
13496 * @return {@code true} if this succeeded.
13498 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13500 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13502 } catch (IllegalArgumentException e) {
13503 if (!suppressLogs) {
13504 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13506 } catch (SecurityException e) {
13507 if (!suppressLogs) {
13508 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13515 * Schedule the given thread an FIFO scheduling priority.
13517 * @param tid the tid of the thread to adjust the scheduling of.
13518 * @param suppressLogs {@code true} if any error logging should be disabled.
13520 * @return {@code true} if this succeeded.
13522 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13524 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13526 } catch (IllegalArgumentException e) {
13527 if (!suppressLogs) {
13528 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13530 } catch (SecurityException e) {
13531 if (!suppressLogs) {
13532 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13539 * Check that we have the features required for VR-related API calls, and throw an exception if
13542 private void enforceSystemHasVrFeature() {
13543 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13544 throw new UnsupportedOperationException("VR mode not supported on this device!");
13549 public void setRenderThread(int tid) {
13550 synchronized (this) {
13551 ProcessRecord proc;
13552 int pid = Binder.getCallingPid();
13553 if (pid == Process.myPid()) {
13554 demoteSystemServerRenderThread(tid);
13557 synchronized (mPidsSelfLocked) {
13558 proc = mPidsSelfLocked.get(pid);
13559 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13560 // ensure the tid belongs to the process
13561 if (!isThreadInProcess(pid, tid)) {
13562 throw new IllegalArgumentException(
13563 "Render thread does not belong to process");
13565 proc.renderThreadTid = tid;
13566 if (DEBUG_OOM_ADJ) {
13567 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13569 // promote to FIFO now
13570 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13571 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13572 if (mUseFifoUiScheduling) {
13573 setThreadScheduler(proc.renderThreadTid,
13574 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13576 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13580 if (DEBUG_OOM_ADJ) {
13581 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13582 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13583 mUseFifoUiScheduling);
13591 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13592 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13594 * @param tid the tid of the RenderThread
13596 private void demoteSystemServerRenderThread(int tid) {
13597 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13601 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13602 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13603 throw new UnsupportedOperationException("VR mode not supported on this device!");
13606 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13609 synchronized (this) {
13610 r = ActivityRecord.isInStackLocked(token);
13614 throw new IllegalArgumentException();
13618 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13619 VrManagerInternal.NO_ERROR) {
13623 synchronized(this) {
13624 r.requestedVrComponent = (enabled) ? packageName : null;
13626 // Update associated state if this activity is currently focused
13627 if (r == mStackSupervisor.getResumedActivityLocked()) {
13628 applyUpdateVrModeLocked(r);
13635 public boolean isVrModePackageEnabled(ComponentName packageName) {
13636 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13637 throw new UnsupportedOperationException("VR mode not supported on this device!");
13640 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13642 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13643 VrManagerInternal.NO_ERROR;
13646 public boolean isTopActivityImmersive() {
13647 enforceNotIsolatedCaller("startActivity");
13648 synchronized (this) {
13649 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13650 return (r != null) ? r.immersive : false;
13655 * @return whether the system should disable UI modes incompatible with VR mode.
13657 boolean shouldDisableNonVrUiLocked() {
13658 return mVrController.shouldDisableNonVrUiLocked();
13662 public boolean isTopOfTask(IBinder token) {
13663 synchronized (this) {
13664 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13666 throw new IllegalArgumentException();
13668 return r.getTask().getTopActivity() == r;
13673 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13674 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13675 String msg = "Permission Denial: setHasTopUi() from pid="
13676 + Binder.getCallingPid()
13677 + ", uid=" + Binder.getCallingUid()
13678 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13680 throw new SecurityException(msg);
13682 final int pid = Binder.getCallingPid();
13683 final long origId = Binder.clearCallingIdentity();
13685 synchronized (this) {
13686 boolean changed = false;
13688 synchronized (mPidsSelfLocked) {
13689 pr = mPidsSelfLocked.get(pid);
13691 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13694 if (pr.hasTopUi != hasTopUi) {
13695 if (DEBUG_OOM_ADJ) {
13696 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13698 pr.hasTopUi = hasTopUi;
13703 updateOomAdjLocked(pr, true);
13707 Binder.restoreCallingIdentity(origId);
13711 public final void enterSafeMode() {
13712 synchronized(this) {
13713 // It only makes sense to do this before the system is ready
13714 // and started launching other packages.
13715 if (!mSystemReady) {
13717 AppGlobals.getPackageManager().enterSafeMode();
13718 } catch (RemoteException e) {
13726 public final void showSafeModeOverlay() {
13727 View v = LayoutInflater.from(mContext).inflate(
13728 com.android.internal.R.layout.safe_mode, null);
13729 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13730 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13731 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13732 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13733 lp.gravity = Gravity.BOTTOM | Gravity.START;
13734 lp.format = v.getBackground().getOpacity();
13735 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13736 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13737 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13738 ((WindowManager)mContext.getSystemService(
13739 Context.WINDOW_SERVICE)).addView(v, lp);
13742 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13743 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13746 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13747 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13748 synchronized (stats) {
13749 if (mBatteryStatsService.isOnBattery()) {
13750 mBatteryStatsService.enforceCallingPermission();
13751 int MY_UID = Binder.getCallingUid();
13753 if (sender == null) {
13756 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13758 BatteryStatsImpl.Uid.Pkg pkg =
13759 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13760 sourcePkg != null ? sourcePkg : rec.key.packageName);
13761 pkg.noteWakeupAlarmLocked(tag);
13766 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13767 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13770 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13771 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13772 synchronized (stats) {
13773 mBatteryStatsService.enforceCallingPermission();
13774 int MY_UID = Binder.getCallingUid();
13776 if (sender == null) {
13779 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13781 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13785 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13786 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13789 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13790 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13791 synchronized (stats) {
13792 mBatteryStatsService.enforceCallingPermission();
13793 int MY_UID = Binder.getCallingUid();
13795 if (sender == null) {
13798 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13800 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13804 public boolean killPids(int[] pids, String pReason, boolean secure) {
13805 if (Binder.getCallingUid() != SYSTEM_UID) {
13806 throw new SecurityException("killPids only available to the system");
13808 String reason = (pReason == null) ? "Unknown" : pReason;
13809 // XXX Note: don't acquire main activity lock here, because the window
13810 // manager calls in with its locks held.
13812 boolean killed = false;
13813 synchronized (mPidsSelfLocked) {
13815 for (int i=0; i<pids.length; i++) {
13816 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13817 if (proc != null) {
13818 int type = proc.setAdj;
13819 if (type > worstType) {
13825 // If the worst oom_adj is somewhere in the cached proc LRU range,
13826 // then constrain it so we will kill all cached procs.
13827 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13828 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13829 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13832 // If this is not a secure call, don't let it kill processes that
13834 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13835 worstType = ProcessList.SERVICE_ADJ;
13838 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13839 for (int i=0; i<pids.length; i++) {
13840 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13841 if (proc == null) {
13844 int adj = proc.setAdj;
13845 if (adj >= worstType && !proc.killedByAm) {
13846 proc.kill(reason, true);
13855 public void killUid(int appId, int userId, String reason) {
13856 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13857 synchronized (this) {
13858 final long identity = Binder.clearCallingIdentity();
13860 killPackageProcessesLocked(null, appId, userId,
13861 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13862 reason != null ? reason : "kill uid");
13864 Binder.restoreCallingIdentity(identity);
13870 public boolean killProcessesBelowForeground(String reason) {
13871 if (Binder.getCallingUid() != SYSTEM_UID) {
13872 throw new SecurityException("killProcessesBelowForeground() only available to system");
13875 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13878 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13879 if (Binder.getCallingUid() != SYSTEM_UID) {
13880 throw new SecurityException("killProcessesBelowAdj() only available to system");
13883 boolean killed = false;
13884 synchronized (mPidsSelfLocked) {
13885 final int size = mPidsSelfLocked.size();
13886 for (int i = 0; i < size; i++) {
13887 final int pid = mPidsSelfLocked.keyAt(i);
13888 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13889 if (proc == null) continue;
13891 final int adj = proc.setAdj;
13892 if (adj > belowAdj && !proc.killedByAm) {
13893 proc.kill(reason, true);
13902 public void hang(final IBinder who, boolean allowRestart) {
13903 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13904 != PackageManager.PERMISSION_GRANTED) {
13905 throw new SecurityException("Requires permission "
13906 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13909 final IBinder.DeathRecipient death = new DeathRecipient() {
13911 public void binderDied() {
13912 synchronized (this) {
13919 who.linkToDeath(death, 0);
13920 } catch (RemoteException e) {
13921 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13925 synchronized (this) {
13926 Watchdog.getInstance().setAllowRestart(allowRestart);
13927 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13928 synchronized (death) {
13929 while (who.isBinderAlive()) {
13932 } catch (InterruptedException e) {
13936 Watchdog.getInstance().setAllowRestart(true);
13941 public void restart() {
13942 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13943 != PackageManager.PERMISSION_GRANTED) {
13944 throw new SecurityException("Requires permission "
13945 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13948 Log.i(TAG, "Sending shutdown broadcast...");
13950 BroadcastReceiver br = new BroadcastReceiver() {
13951 @Override public void onReceive(Context context, Intent intent) {
13952 // Now the broadcast is done, finish up the low-level shutdown.
13953 Log.i(TAG, "Shutting down activity manager...");
13955 Log.i(TAG, "Shutdown complete, restarting!");
13956 killProcess(myPid());
13961 // First send the high-level shut down broadcast.
13962 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13963 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13964 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13965 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13966 mContext.sendOrderedBroadcastAsUser(intent,
13967 UserHandle.ALL, null, br, mHandler, 0, null, null);
13969 br.onReceive(mContext, intent);
13972 private long getLowRamTimeSinceIdle(long now) {
13973 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13977 public void performIdleMaintenance() {
13978 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13979 != PackageManager.PERMISSION_GRANTED) {
13980 throw new SecurityException("Requires permission "
13981 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13984 synchronized (this) {
13985 final long now = SystemClock.uptimeMillis();
13986 final long timeSinceLastIdle = now - mLastIdleTime;
13987 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13988 mLastIdleTime = now;
13989 mLowRamTimeSinceLastIdle = 0;
13990 if (mLowRamStartTime != 0) {
13991 mLowRamStartTime = now;
13994 StringBuilder sb = new StringBuilder(128);
13995 sb.append("Idle maintenance over ");
13996 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13997 sb.append(" low RAM for ");
13998 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13999 Slog.i(TAG, sb.toString());
14001 // If at least 1/3 of our time since the last idle period has been spent
14002 // with RAM low, then we want to kill processes.
14003 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14005 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14006 ProcessRecord proc = mLruProcesses.get(i);
14007 if (proc.notCachedSinceIdle) {
14008 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14009 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14010 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14011 if (doKilling && proc.initialIdlePss != 0
14012 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14013 sb = new StringBuilder(128);
14015 sb.append(proc.processName);
14016 sb.append(" in idle maint: pss=");
14017 sb.append(proc.lastPss);
14018 sb.append(", swapPss=");
14019 sb.append(proc.lastSwapPss);
14020 sb.append(", initialPss=");
14021 sb.append(proc.initialIdlePss);
14022 sb.append(", period=");
14023 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14024 sb.append(", lowRamPeriod=");
14025 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14026 Slog.wtfQuiet(TAG, sb.toString());
14027 proc.kill("idle maint (pss " + proc.lastPss
14028 + " from " + proc.initialIdlePss + ")", true);
14031 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14032 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14033 proc.notCachedSinceIdle = true;
14034 proc.initialIdlePss = 0;
14035 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14036 mTestPssMode, isSleepingLocked(), now);
14040 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14041 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14046 public void sendIdleJobTrigger() {
14047 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14048 != PackageManager.PERMISSION_GRANTED) {
14049 throw new SecurityException("Requires permission "
14050 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14053 final long ident = Binder.clearCallingIdentity();
14055 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14056 .setPackage("android")
14057 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14058 broadcastIntent(null, intent, null, null, 0, null, null, null,
14059 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14061 Binder.restoreCallingIdentity(ident);
14065 private void retrieveSettings() {
14066 final ContentResolver resolver = mContext.getContentResolver();
14067 final boolean freeformWindowManagement =
14068 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14069 || Settings.Global.getInt(
14070 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14072 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14073 final boolean supportsPictureInPicture = supportsMultiWindow &&
14074 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14075 final boolean supportsSplitScreenMultiWindow =
14076 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14077 final boolean supportsMultiDisplay = mContext.getPackageManager()
14078 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14079 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14080 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14081 final boolean alwaysFinishActivities =
14082 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14083 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14084 final boolean forceResizable = Settings.Global.getInt(
14085 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14086 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14087 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14088 final boolean supportsLeanbackOnly =
14089 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14091 // Transfer any global setting for forcing RTL layout, into a System Property
14092 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14094 final Configuration configuration = new Configuration();
14095 Settings.System.getConfiguration(resolver, configuration);
14097 // This will take care of setting the correct layout direction flags
14098 configuration.setLayoutDirection(configuration.locale);
14101 synchronized (this) {
14102 mDebugApp = mOrigDebugApp = debugApp;
14103 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14104 mAlwaysFinishActivities = alwaysFinishActivities;
14105 mSupportsLeanbackOnly = supportsLeanbackOnly;
14106 mForceResizableActivities = forceResizable;
14107 final boolean multiWindowFormEnabled = freeformWindowManagement
14108 || supportsSplitScreenMultiWindow
14109 || supportsPictureInPicture
14110 || supportsMultiDisplay;
14111 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14112 mSupportsMultiWindow = true;
14113 mSupportsFreeformWindowManagement = freeformWindowManagement;
14114 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14115 mSupportsPictureInPicture = supportsPictureInPicture;
14116 mSupportsMultiDisplay = supportsMultiDisplay;
14118 mSupportsMultiWindow = false;
14119 mSupportsFreeformWindowManagement = false;
14120 mSupportsSplitScreenMultiWindow = false;
14121 mSupportsPictureInPicture = false;
14122 mSupportsMultiDisplay = false;
14124 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14125 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14126 // This happens before any activities are started, so we can change global configuration
14128 updateConfigurationLocked(configuration, null, true);
14129 final Configuration globalConfig = getGlobalConfiguration();
14130 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14132 // Load resources only after the current configuration has been set.
14133 final Resources res = mContext.getResources();
14134 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14135 mThumbnailWidth = res.getDimensionPixelSize(
14136 com.android.internal.R.dimen.thumbnail_width);
14137 mThumbnailHeight = res.getDimensionPixelSize(
14138 com.android.internal.R.dimen.thumbnail_height);
14139 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14140 com.android.internal.R.string.config_appsNotReportingCrashes));
14141 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14142 com.android.internal.R.bool.config_customUserSwitchUi);
14143 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14144 mFullscreenThumbnailScale = (float) res
14145 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14146 (float) globalConfig.screenWidthDp;
14148 mFullscreenThumbnailScale = res.getFraction(
14149 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14151 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14155 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14156 traceLog.traceBegin("PhaseActivityManagerReady");
14157 synchronized(this) {
14158 if (mSystemReady) {
14159 // If we're done calling all the receivers, run the next "boot phase" passed in
14160 // by the SystemServer
14161 if (goingCallback != null) {
14162 goingCallback.run();
14167 mLocalDeviceIdleController
14168 = LocalServices.getService(DeviceIdleController.LocalService.class);
14169 mAssistUtils = new AssistUtils(mContext);
14170 mVrController.onSystemReady();
14171 // Make sure we have the current profile info, since it is needed for security checks.
14172 mUserController.onSystemReady();
14173 mRecentTasks.onSystemReadyLocked();
14174 mAppOpsService.systemReady();
14175 mSystemReady = true;
14179 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14180 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14182 } catch (RemoteException e) {}
14184 ArrayList<ProcessRecord> procsToKill = null;
14185 synchronized(mPidsSelfLocked) {
14186 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14187 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14188 if (!isAllowedWhileBooting(proc.info)){
14189 if (procsToKill == null) {
14190 procsToKill = new ArrayList<ProcessRecord>();
14192 procsToKill.add(proc);
14197 synchronized(this) {
14198 if (procsToKill != null) {
14199 for (int i=procsToKill.size()-1; i>=0; i--) {
14200 ProcessRecord proc = procsToKill.get(i);
14201 Slog.i(TAG, "Removing system update proc: " + proc);
14202 removeProcessLocked(proc, true, false, "system update done");
14206 // Now that we have cleaned up any update processes, we
14207 // are ready to start launching real processes and know that
14208 // we won't trample on them any more.
14209 mProcessesReady = true;
14212 Slog.i(TAG, "System now ready");
14213 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14214 SystemClock.uptimeMillis());
14216 synchronized(this) {
14217 // Make sure we have no pre-ready processes sitting around.
14219 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14220 ResolveInfo ri = mContext.getPackageManager()
14221 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14223 CharSequence errorMsg = null;
14225 ActivityInfo ai = ri.activityInfo;
14226 ApplicationInfo app = ai.applicationInfo;
14227 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14228 mTopAction = Intent.ACTION_FACTORY_TEST;
14230 mTopComponent = new ComponentName(app.packageName,
14233 errorMsg = mContext.getResources().getText(
14234 com.android.internal.R.string.factorytest_not_system);
14237 errorMsg = mContext.getResources().getText(
14238 com.android.internal.R.string.factorytest_no_action);
14240 if (errorMsg != null) {
14243 mTopComponent = null;
14244 Message msg = Message.obtain();
14245 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14246 msg.getData().putCharSequence("msg", errorMsg);
14247 mUiHandler.sendMessage(msg);
14252 retrieveSettings();
14253 final int currentUserId;
14254 synchronized (this) {
14255 currentUserId = mUserController.getCurrentUserIdLocked();
14256 readGrantedUriPermissionsLocked();
14259 if (goingCallback != null) goingCallback.run();
14260 traceLog.traceBegin("ActivityManagerStartApps");
14261 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14262 Integer.toString(currentUserId), currentUserId);
14263 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14264 Integer.toString(currentUserId), currentUserId);
14265 mSystemServiceManager.startUser(currentUserId);
14267 synchronized (this) {
14268 // Only start up encryption-aware persistent apps; once user is
14269 // unlocked we'll come back around and start unaware apps
14270 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14272 // Start up initial activity.
14274 // Enable home activity for system user, so that the system can always boot. We don't
14275 // do this when the system user is not setup since the setup wizard should be the one
14276 // to handle home activity in this case.
14277 if (UserManager.isSplitSystemUser() &&
14278 Settings.Secure.getInt(mContext.getContentResolver(),
14279 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14280 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14282 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14283 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14284 UserHandle.USER_SYSTEM);
14285 } catch (RemoteException e) {
14286 throw e.rethrowAsRuntimeException();
14289 startHomeActivityLocked(currentUserId, "systemReady");
14292 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14293 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14294 + " data partition or your device will be unstable.");
14295 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14297 } catch (RemoteException e) {
14300 if (!Build.isBuildConsistent()) {
14301 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14302 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14305 long ident = Binder.clearCallingIdentity();
14307 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14308 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14309 | Intent.FLAG_RECEIVER_FOREGROUND);
14310 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14311 broadcastIntentLocked(null, null, intent,
14312 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14313 null, false, false, MY_PID, SYSTEM_UID,
14315 intent = new Intent(Intent.ACTION_USER_STARTING);
14316 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14317 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14318 broadcastIntentLocked(null, null, intent,
14319 null, new IIntentReceiver.Stub() {
14321 public void performReceive(Intent intent, int resultCode, String data,
14322 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14323 throws RemoteException {
14326 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14327 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14328 } catch (Throwable t) {
14329 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14331 Binder.restoreCallingIdentity(ident);
14333 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14334 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14335 traceLog.traceEnd(); // ActivityManagerStartApps
14336 traceLog.traceEnd(); // PhaseActivityManagerReady
14340 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14341 synchronized (this) {
14342 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14346 void skipCurrentReceiverLocked(ProcessRecord app) {
14347 for (BroadcastQueue queue : mBroadcastQueues) {
14348 queue.skipCurrentReceiverLocked(app);
14353 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14354 * The application process will exit immediately after this call returns.
14355 * @param app object of the crashing app, null for the system server
14356 * @param crashInfo describing the exception
14358 public void handleApplicationCrash(IBinder app,
14359 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14360 ProcessRecord r = findAppProcess(app, "Crash");
14361 final String processName = app == null ? "system_server"
14362 : (r == null ? "unknown" : r.processName);
14364 handleApplicationCrashInner("crash", r, processName, crashInfo);
14367 /* Native crash reporting uses this inner version because it needs to be somewhat
14368 * decoupled from the AM-managed cleanup lifecycle
14370 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14371 ApplicationErrorReport.CrashInfo crashInfo) {
14372 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14373 UserHandle.getUserId(Binder.getCallingUid()), processName,
14374 r == null ? -1 : r.info.flags,
14375 crashInfo.exceptionClassName,
14376 crashInfo.exceptionMessage,
14377 crashInfo.throwFileName,
14378 crashInfo.throwLineNumber);
14380 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14382 mAppErrors.crashApplication(r, crashInfo);
14385 public void handleApplicationStrictModeViolation(
14388 StrictMode.ViolationInfo info) {
14389 ProcessRecord r = findAppProcess(app, "StrictMode");
14394 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14395 Integer stackFingerprint = info.hashCode();
14396 boolean logIt = true;
14397 synchronized (mAlreadyLoggedViolatedStacks) {
14398 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14400 // TODO: sub-sample into EventLog for these, with
14401 // the info.durationMillis? Then we'd get
14402 // the relative pain numbers, without logging all
14403 // the stack traces repeatedly. We'd want to do
14404 // likewise in the client code, which also does
14405 // dup suppression, before the Binder call.
14407 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14408 mAlreadyLoggedViolatedStacks.clear();
14410 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14414 logStrictModeViolationToDropBox(r, info);
14418 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14419 AppErrorResult result = new AppErrorResult();
14420 synchronized (this) {
14421 final long origId = Binder.clearCallingIdentity();
14423 Message msg = Message.obtain();
14424 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14425 HashMap<String, Object> data = new HashMap<String, Object>();
14426 data.put("result", result);
14427 data.put("app", r);
14428 data.put("violationMask", violationMask);
14429 data.put("info", info);
14431 mUiHandler.sendMessage(msg);
14433 Binder.restoreCallingIdentity(origId);
14435 int res = result.get();
14436 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14440 // Depending on the policy in effect, there could be a bunch of
14441 // these in quick succession so we try to batch these together to
14442 // minimize disk writes, number of dropbox entries, and maximize
14443 // compression, by having more fewer, larger records.
14444 private void logStrictModeViolationToDropBox(
14445 ProcessRecord process,
14446 StrictMode.ViolationInfo info) {
14447 if (info == null) {
14450 final boolean isSystemApp = process == null ||
14451 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14452 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14453 final String processName = process == null ? "unknown" : process.processName;
14454 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14455 final DropBoxManager dbox = (DropBoxManager)
14456 mContext.getSystemService(Context.DROPBOX_SERVICE);
14458 // Exit early if the dropbox isn't configured to accept this report type.
14459 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14461 boolean bufferWasEmpty;
14462 boolean needsFlush;
14463 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14464 synchronized (sb) {
14465 bufferWasEmpty = sb.length() == 0;
14466 appendDropBoxProcessHeaders(process, processName, sb);
14467 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14468 sb.append("System-App: ").append(isSystemApp).append("\n");
14469 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14470 if (info.violationNumThisLoop != 0) {
14471 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14473 if (info.numAnimationsRunning != 0) {
14474 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14476 if (info.broadcastIntentAction != null) {
14477 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14479 if (info.durationMillis != -1) {
14480 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14482 if (info.numInstances != -1) {
14483 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14485 if (info.tags != null) {
14486 for (String tag : info.tags) {
14487 sb.append("Span-Tag: ").append(tag).append("\n");
14491 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14492 sb.append(info.crashInfo.stackTrace);
14495 if (info.message != null) {
14496 sb.append(info.message);
14500 // Only buffer up to ~64k. Various logging bits truncate
14502 needsFlush = (sb.length() > 64 * 1024);
14505 // Flush immediately if the buffer's grown too large, or this
14506 // is a non-system app. Non-system apps are isolated with a
14507 // different tag & policy and not batched.
14509 // Batching is useful during internal testing with
14510 // StrictMode settings turned up high. Without batching,
14511 // thousands of separate files could be created on boot.
14512 if (!isSystemApp || needsFlush) {
14513 new Thread("Error dump: " + dropboxTag) {
14515 public void run() {
14517 synchronized (sb) {
14518 report = sb.toString();
14519 sb.delete(0, sb.length());
14522 if (report.length() != 0) {
14523 dbox.addText(dropboxTag, report);
14530 // System app batching:
14531 if (!bufferWasEmpty) {
14532 // An existing dropbox-writing thread is outstanding, so
14533 // we don't need to start it up. The existing thread will
14534 // catch the buffer appends we just did.
14538 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14539 // (After this point, we shouldn't access AMS internal data structures.)
14540 new Thread("Error dump: " + dropboxTag) {
14542 public void run() {
14543 // 5 second sleep to let stacks arrive and be batched together
14545 Thread.sleep(5000); // 5 seconds
14546 } catch (InterruptedException e) {}
14548 String errorReport;
14549 synchronized (mStrictModeBuffer) {
14550 errorReport = mStrictModeBuffer.toString();
14551 if (errorReport.length() == 0) {
14554 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14555 mStrictModeBuffer.trimToSize();
14557 dbox.addText(dropboxTag, errorReport);
14563 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14564 * @param app object of the crashing app, null for the system server
14565 * @param tag reported by the caller
14566 * @param system whether this wtf is coming from the system
14567 * @param crashInfo describing the context of the error
14568 * @return true if the process should exit immediately (WTF is fatal)
14570 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14571 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14572 final int callingUid = Binder.getCallingUid();
14573 final int callingPid = Binder.getCallingPid();
14576 // If this is coming from the system, we could very well have low-level
14577 // system locks held, so we want to do this all asynchronously. And we
14578 // never want this to become fatal, so there is that too.
14579 mHandler.post(new Runnable() {
14580 @Override public void run() {
14581 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14587 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14590 final boolean isFatal = Build.IS_ENG || Settings.Global
14591 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14592 final boolean isSystem = (r == null) || r.persistent;
14594 if (isFatal && !isSystem) {
14595 mAppErrors.crashApplication(r, crashInfo);
14602 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14603 final ApplicationErrorReport.CrashInfo crashInfo) {
14604 final ProcessRecord r = findAppProcess(app, "WTF");
14605 final String processName = app == null ? "system_server"
14606 : (r == null ? "unknown" : r.processName);
14608 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14609 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14611 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14617 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14618 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14620 private ProcessRecord findAppProcess(IBinder app, String reason) {
14625 synchronized (this) {
14626 final int NP = mProcessNames.getMap().size();
14627 for (int ip=0; ip<NP; ip++) {
14628 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14629 final int NA = apps.size();
14630 for (int ia=0; ia<NA; ia++) {
14631 ProcessRecord p = apps.valueAt(ia);
14632 if (p.thread != null && p.thread.asBinder() == app) {
14638 Slog.w(TAG, "Can't find mystery application for " + reason
14639 + " from pid=" + Binder.getCallingPid()
14640 + " uid=" + Binder.getCallingUid() + ": " + app);
14646 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14647 * to append various headers to the dropbox log text.
14649 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14650 StringBuilder sb) {
14651 // Watchdog thread ends up invoking this function (with
14652 // a null ProcessRecord) to add the stack file to dropbox.
14653 // Do not acquire a lock on this (am) in such cases, as it
14654 // could cause a potential deadlock, if and when watchdog
14655 // is invoked due to unavailability of lock on am and it
14656 // would prevent watchdog from killing system_server.
14657 if (process == null) {
14658 sb.append("Process: ").append(processName).append("\n");
14661 // Note: ProcessRecord 'process' is guarded by the service
14662 // instance. (notably process.pkgList, which could otherwise change
14663 // concurrently during execution of this method)
14664 synchronized (this) {
14665 sb.append("Process: ").append(processName).append("\n");
14666 sb.append("PID: ").append(process.pid).append("\n");
14667 int flags = process.info.flags;
14668 IPackageManager pm = AppGlobals.getPackageManager();
14669 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14670 for (int ip=0; ip<process.pkgList.size(); ip++) {
14671 String pkg = process.pkgList.keyAt(ip);
14672 sb.append("Package: ").append(pkg);
14674 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14676 sb.append(" v").append(pi.versionCode);
14677 if (pi.versionName != null) {
14678 sb.append(" (").append(pi.versionName).append(")");
14681 } catch (RemoteException e) {
14682 Slog.e(TAG, "Error getting package info: " + pkg, e);
14686 if (process.info.isInstantApp()) {
14687 sb.append("Instant-App: true\n");
14692 private static String processClass(ProcessRecord process) {
14693 if (process == null || process.pid == MY_PID) {
14694 return "system_server";
14695 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14696 return "system_app";
14702 private volatile long mWtfClusterStart;
14703 private volatile int mWtfClusterCount;
14706 * Write a description of an error (crash, WTF, ANR) to the drop box.
14707 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14708 * @param process which caused the error, null means the system server
14709 * @param activity which triggered the error, null if unknown
14710 * @param parent activity related to the error, null if unknown
14711 * @param subject line related to the error, null if absent
14712 * @param report in long form describing the error, null if absent
14713 * @param dataFile text file to include in the report, null if none
14714 * @param crashInfo giving an application stack trace, null if absent
14716 public void addErrorToDropBox(String eventType,
14717 ProcessRecord process, String processName, ActivityRecord activity,
14718 ActivityRecord parent, String subject,
14719 final String report, final File dataFile,
14720 final ApplicationErrorReport.CrashInfo crashInfo) {
14721 // NOTE -- this must never acquire the ActivityManagerService lock,
14722 // otherwise the watchdog may be prevented from resetting the system.
14724 // Bail early if not published yet
14725 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14726 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14728 // Exit early if the dropbox isn't configured to accept this report type.
14729 final String dropboxTag = processClass(process) + "_" + eventType;
14730 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14732 // Rate-limit how often we're willing to do the heavy lifting below to
14733 // collect and record logs; currently 5 logs per 10 second period.
14734 final long now = SystemClock.elapsedRealtime();
14735 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14736 mWtfClusterStart = now;
14737 mWtfClusterCount = 1;
14739 if (mWtfClusterCount++ >= 5) return;
14742 final StringBuilder sb = new StringBuilder(1024);
14743 appendDropBoxProcessHeaders(process, processName, sb);
14744 if (process != null) {
14745 sb.append("Foreground: ")
14746 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14749 if (activity != null) {
14750 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14752 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14753 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14755 if (parent != null && parent != activity) {
14756 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14758 if (subject != null) {
14759 sb.append("Subject: ").append(subject).append("\n");
14761 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14762 if (Debug.isDebuggerConnected()) {
14763 sb.append("Debugger: Connected\n");
14767 // Do the rest in a worker thread to avoid blocking the caller on I/O
14768 // (After this point, we shouldn't access AMS internal data structures.)
14769 Thread worker = new Thread("Error dump: " + dropboxTag) {
14771 public void run() {
14772 if (report != null) {
14776 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14777 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14778 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14779 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14781 if (dataFile != null && maxDataFileSize > 0) {
14783 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14784 "\n\n[[TRUNCATED]]"));
14785 } catch (IOException e) {
14786 Slog.e(TAG, "Error reading " + dataFile, e);
14789 if (crashInfo != null && crashInfo.stackTrace != null) {
14790 sb.append(crashInfo.stackTrace);
14796 // Merge several logcat streams, and take the last N lines
14797 InputStreamReader input = null;
14799 java.lang.Process logcat = new ProcessBuilder(
14800 "/system/bin/timeout", "-k", "15s", "10s",
14801 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14802 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14803 .redirectErrorStream(true).start();
14805 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14806 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14807 input = new InputStreamReader(logcat.getInputStream());
14810 char[] buf = new char[8192];
14811 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14812 } catch (IOException e) {
14813 Slog.e(TAG, "Error running logcat", e);
14815 if (input != null) try { input.close(); } catch (IOException e) {}
14819 dbox.addText(dropboxTag, sb.toString());
14823 if (process == null) {
14824 // If process is null, we are being called from some internal code
14825 // and may be about to die -- run this synchronously.
14833 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14834 enforceNotIsolatedCaller("getProcessesInErrorState");
14835 // assume our apps are happy - lazy create the list
14836 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14838 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14839 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14840 int userId = UserHandle.getUserId(Binder.getCallingUid());
14842 synchronized (this) {
14844 // iterate across all processes
14845 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14846 ProcessRecord app = mLruProcesses.get(i);
14847 if (!allUsers && app.userId != userId) {
14850 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14851 // This one's in trouble, so we'll generate a report for it
14852 // crashes are higher priority (in case there's a crash *and* an anr)
14853 ActivityManager.ProcessErrorStateInfo report = null;
14854 if (app.crashing) {
14855 report = app.crashingReport;
14856 } else if (app.notResponding) {
14857 report = app.notRespondingReport;
14860 if (report != null) {
14861 if (errList == null) {
14862 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14864 errList.add(report);
14866 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14867 " crashing = " + app.crashing +
14868 " notResponding = " + app.notResponding);
14877 static int procStateToImportance(int procState, int memAdj,
14878 ActivityManager.RunningAppProcessInfo currApp,
14879 int clientTargetSdk) {
14880 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14881 procState, clientTargetSdk);
14882 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14883 currApp.lru = memAdj;
14890 private void fillInProcMemInfo(ProcessRecord app,
14891 ActivityManager.RunningAppProcessInfo outInfo,
14892 int clientTargetSdk) {
14893 outInfo.pid = app.pid;
14894 outInfo.uid = app.info.uid;
14895 if (mHeavyWeightProcess == app) {
14896 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14898 if (app.persistent) {
14899 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14901 if (app.activities.size() > 0) {
14902 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14904 outInfo.lastTrimLevel = app.trimMemoryLevel;
14905 int adj = app.curAdj;
14906 int procState = app.curProcState;
14907 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14908 outInfo.importanceReasonCode = app.adjTypeCode;
14909 outInfo.processState = app.curProcState;
14913 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14914 enforceNotIsolatedCaller("getRunningAppProcesses");
14916 final int callingUid = Binder.getCallingUid();
14917 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14919 // Lazy instantiation of list
14920 List<ActivityManager.RunningAppProcessInfo> runList = null;
14921 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14922 callingUid) == PackageManager.PERMISSION_GRANTED;
14923 final int userId = UserHandle.getUserId(callingUid);
14924 final boolean allUids = isGetTasksAllowed(
14925 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14927 synchronized (this) {
14928 // Iterate across all processes
14929 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14930 ProcessRecord app = mLruProcesses.get(i);
14931 if ((!allUsers && app.userId != userId)
14932 || (!allUids && app.uid != callingUid)) {
14935 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14936 // Generate process state info for running application
14937 ActivityManager.RunningAppProcessInfo currApp =
14938 new ActivityManager.RunningAppProcessInfo(app.processName,
14939 app.pid, app.getPackageList());
14940 fillInProcMemInfo(app, currApp, clientTargetSdk);
14941 if (app.adjSource instanceof ProcessRecord) {
14942 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14943 currApp.importanceReasonImportance =
14944 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14945 app.adjSourceProcState);
14946 } else if (app.adjSource instanceof ActivityRecord) {
14947 ActivityRecord r = (ActivityRecord)app.adjSource;
14948 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14950 if (app.adjTarget instanceof ComponentName) {
14951 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14953 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14954 // + " lru=" + currApp.lru);
14955 if (runList == null) {
14956 runList = new ArrayList<>();
14958 runList.add(currApp);
14966 public List<ApplicationInfo> getRunningExternalApplications() {
14967 enforceNotIsolatedCaller("getRunningExternalApplications");
14968 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14969 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14970 if (runningApps != null && runningApps.size() > 0) {
14971 Set<String> extList = new HashSet<String>();
14972 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14973 if (app.pkgList != null) {
14974 for (String pkg : app.pkgList) {
14979 IPackageManager pm = AppGlobals.getPackageManager();
14980 for (String pkg : extList) {
14982 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14983 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14986 } catch (RemoteException e) {
14994 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14995 enforceNotIsolatedCaller("getMyMemoryState");
14997 final int callingUid = Binder.getCallingUid();
14998 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15000 synchronized (this) {
15001 ProcessRecord proc;
15002 synchronized (mPidsSelfLocked) {
15003 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15005 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15010 public int getMemoryTrimLevel() {
15011 enforceNotIsolatedCaller("getMyMemoryState");
15012 synchronized (this) {
15013 return mLastMemoryLevel;
15018 public void onShellCommand(FileDescriptor in, FileDescriptor out,
15019 FileDescriptor err, String[] args, ShellCallback callback,
15020 ResultReceiver resultReceiver) {
15021 (new ActivityManagerShellCommand(this, false)).exec(
15022 this, in, out, err, args, callback, resultReceiver);
15025 SleepToken acquireSleepToken(String tag, int displayId) {
15026 synchronized (this) {
15027 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15028 updateSleepIfNeededLocked();
15034 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15035 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15037 boolean dumpAll = false;
15038 boolean dumpClient = false;
15039 boolean dumpCheckin = false;
15040 boolean dumpCheckinFormat = false;
15041 boolean dumpVisibleStacksOnly = false;
15042 boolean dumpFocusedStackOnly = false;
15043 String dumpPackage = null;
15046 while (opti < args.length) {
15047 String opt = args[opti];
15048 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15052 if ("-a".equals(opt)) {
15054 } else if ("-c".equals(opt)) {
15056 } else if ("-v".equals(opt)) {
15057 dumpVisibleStacksOnly = true;
15058 } else if ("-f".equals(opt)) {
15059 dumpFocusedStackOnly = true;
15060 } else if ("-p".equals(opt)) {
15061 if (opti < args.length) {
15062 dumpPackage = args[opti];
15065 pw.println("Error: -p option requires package argument");
15069 } else if ("--checkin".equals(opt)) {
15070 dumpCheckin = dumpCheckinFormat = true;
15071 } else if ("-C".equals(opt)) {
15072 dumpCheckinFormat = true;
15073 } else if ("-h".equals(opt)) {
15074 ActivityManagerShellCommand.dumpHelp(pw, true);
15077 pw.println("Unknown argument: " + opt + "; use -h for help");
15081 long origId = Binder.clearCallingIdentity();
15082 boolean more = false;
15083 // Is the caller requesting to dump a particular piece of data?
15084 if (opti < args.length) {
15085 String cmd = args[opti];
15087 if ("activities".equals(cmd) || "a".equals(cmd)) {
15088 synchronized (this) {
15089 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15091 } else if ("lastanr".equals(cmd)) {
15092 synchronized (this) {
15093 dumpLastANRLocked(pw);
15095 } else if ("starter".equals(cmd)) {
15096 synchronized (this) {
15097 dumpActivityStarterLocked(pw, dumpPackage);
15099 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15100 synchronized (this) {
15101 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15103 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15106 if (opti >= args.length) {
15108 newArgs = EMPTY_STRING_ARRAY;
15110 dumpPackage = args[opti];
15112 newArgs = new String[args.length - opti];
15113 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15114 args.length - opti);
15116 synchronized (this) {
15117 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15119 } else if ("broadcast-stats".equals(cmd)) {
15122 if (opti >= args.length) {
15124 newArgs = EMPTY_STRING_ARRAY;
15126 dumpPackage = args[opti];
15128 newArgs = new String[args.length - opti];
15129 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15130 args.length - opti);
15132 synchronized (this) {
15133 if (dumpCheckinFormat) {
15134 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15137 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15140 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15143 if (opti >= args.length) {
15145 newArgs = EMPTY_STRING_ARRAY;
15147 dumpPackage = args[opti];
15149 newArgs = new String[args.length - opti];
15150 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15151 args.length - opti);
15153 synchronized (this) {
15154 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15156 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15159 if (opti >= args.length) {
15161 newArgs = EMPTY_STRING_ARRAY;
15163 dumpPackage = args[opti];
15165 newArgs = new String[args.length - opti];
15166 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15167 args.length - opti);
15169 synchronized (this) {
15170 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15172 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15173 synchronized (this) {
15174 dumpOomLocked(fd, pw, args, opti, true);
15176 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15177 synchronized (this) {
15178 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15180 } else if ("provider".equals(cmd)) {
15183 if (opti >= args.length) {
15185 newArgs = EMPTY_STRING_ARRAY;
15189 newArgs = new String[args.length - opti];
15190 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15192 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15193 pw.println("No providers match: " + name);
15194 pw.println("Use -h for help.");
15196 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15197 synchronized (this) {
15198 dumpProvidersLocked(fd, pw, args, opti, true, null);
15200 } else if ("service".equals(cmd)) {
15203 if (opti >= args.length) {
15205 newArgs = EMPTY_STRING_ARRAY;
15209 newArgs = new String[args.length - opti];
15210 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15211 args.length - opti);
15213 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15214 pw.println("No services match: " + name);
15215 pw.println("Use -h for help.");
15217 } else if ("package".equals(cmd)) {
15219 if (opti >= args.length) {
15220 pw.println("package: no package name specified");
15221 pw.println("Use -h for help.");
15223 dumpPackage = args[opti];
15225 newArgs = new String[args.length - opti];
15226 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15227 args.length - opti);
15232 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15233 synchronized (this) {
15234 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15236 } else if ("settings".equals(cmd)) {
15237 synchronized (this) {
15238 mConstants.dump(pw);
15240 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15242 ActiveServices.ServiceDumper dumper;
15243 synchronized (this) {
15244 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15247 dumper.dumpWithClient();
15249 synchronized (this) {
15250 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15251 dumpPackage).dumpLocked();
15254 } else if ("locks".equals(cmd)) {
15255 LockGuard.dump(fd, pw, args);
15257 // Dumping a single activity?
15258 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15259 dumpFocusedStackOnly)) {
15260 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15261 int res = shell.exec(this, null, fd, null, args, null,
15262 new ResultReceiver(null));
15264 pw.println("Bad activity command, or no activities match: " + cmd);
15265 pw.println("Use -h for help.");
15270 Binder.restoreCallingIdentity(origId);
15275 // No piece of data specified, dump everything.
15276 if (dumpCheckinFormat) {
15277 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15278 } else if (dumpClient) {
15279 ActiveServices.ServiceDumper sdumper;
15280 synchronized (this) {
15281 mConstants.dump(pw);
15284 pw.println("-------------------------------------------------------------------------------");
15286 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15289 pw.println("-------------------------------------------------------------------------------");
15291 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15294 pw.println("-------------------------------------------------------------------------------");
15296 if (dumpAll || dumpPackage != null) {
15297 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15300 pw.println("-------------------------------------------------------------------------------");
15303 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15306 pw.println("-------------------------------------------------------------------------------");
15308 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15311 pw.println("-------------------------------------------------------------------------------");
15313 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15316 sdumper.dumpWithClient();
15318 synchronized (this) {
15320 pw.println("-------------------------------------------------------------------------------");
15322 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15325 pw.println("-------------------------------------------------------------------------------");
15327 dumpLastANRLocked(pw);
15330 pw.println("-------------------------------------------------------------------------------");
15332 dumpActivityStarterLocked(pw, dumpPackage);
15335 pw.println("-------------------------------------------------------------------------------");
15337 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15338 if (mAssociations.size() > 0) {
15341 pw.println("-------------------------------------------------------------------------------");
15343 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15347 pw.println("-------------------------------------------------------------------------------");
15349 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15353 synchronized (this) {
15354 mConstants.dump(pw);
15357 pw.println("-------------------------------------------------------------------------------");
15359 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15362 pw.println("-------------------------------------------------------------------------------");
15364 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15367 pw.println("-------------------------------------------------------------------------------");
15369 if (dumpAll || dumpPackage != null) {
15370 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15373 pw.println("-------------------------------------------------------------------------------");
15376 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15379 pw.println("-------------------------------------------------------------------------------");
15381 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15384 pw.println("-------------------------------------------------------------------------------");
15386 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15390 pw.println("-------------------------------------------------------------------------------");
15392 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15395 pw.println("-------------------------------------------------------------------------------");
15397 dumpLastANRLocked(pw);
15400 pw.println("-------------------------------------------------------------------------------");
15402 dumpActivityStarterLocked(pw, dumpPackage);
15405 pw.println("-------------------------------------------------------------------------------");
15407 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15408 if (mAssociations.size() > 0) {
15411 pw.println("-------------------------------------------------------------------------------");
15413 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15417 pw.println("-------------------------------------------------------------------------------");
15419 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15422 Binder.restoreCallingIdentity(origId);
15425 private void dumpLastANRLocked(PrintWriter pw) {
15426 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15427 if (mLastANRState == null) {
15428 pw.println(" <no ANR has occurred since boot>");
15430 pw.println(mLastANRState);
15434 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15435 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15436 mActivityStarter.dump(pw, "", dumpPackage);
15439 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15440 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15441 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15442 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15445 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15446 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15447 pw.println(header);
15449 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15451 boolean needSep = printedAnything;
15453 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15454 mStackSupervisor.getResumedActivityLocked(),
15455 dumpPackage, needSep, " ResumedActivity: ");
15457 printedAnything = true;
15461 if (dumpPackage == null) {
15465 printedAnything = true;
15466 mStackSupervisor.dump(pw, " ");
15469 if (!printedAnything) {
15470 pw.println(" (nothing)");
15474 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15475 int opti, boolean dumpAll, String dumpPackage) {
15476 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15478 boolean printedAnything = false;
15480 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15481 boolean printedHeader = false;
15483 final int N = mRecentTasks.size();
15484 for (int i=0; i<N; i++) {
15485 TaskRecord tr = mRecentTasks.get(i);
15486 if (dumpPackage != null) {
15487 if (tr.realActivity == null ||
15488 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15492 if (!printedHeader) {
15493 pw.println(" Recent tasks:");
15494 printedHeader = true;
15495 printedAnything = true;
15497 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15500 mRecentTasks.get(i).dump(pw, " ");
15505 if (!printedAnything) {
15506 pw.println(" (nothing)");
15510 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15511 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15512 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15515 if (dumpPackage != null) {
15516 IPackageManager pm = AppGlobals.getPackageManager();
15518 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15519 } catch (RemoteException e) {
15523 boolean printedAnything = false;
15525 final long now = SystemClock.uptimeMillis();
15527 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15528 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15529 = mAssociations.valueAt(i1);
15530 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15531 SparseArray<ArrayMap<String, Association>> sourceUids
15532 = targetComponents.valueAt(i2);
15533 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15534 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15535 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15536 Association ass = sourceProcesses.valueAt(i4);
15537 if (dumpPackage != null) {
15538 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15539 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15543 printedAnything = true;
15545 pw.print(ass.mTargetProcess);
15547 UserHandle.formatUid(pw, ass.mTargetUid);
15549 pw.print(ass.mSourceProcess);
15551 UserHandle.formatUid(pw, ass.mSourceUid);
15554 pw.print(ass.mTargetComponent.flattenToShortString());
15557 long dur = ass.mTime;
15558 if (ass.mNesting > 0) {
15559 dur += now - ass.mStartTime;
15561 TimeUtils.formatDuration(dur, pw);
15563 pw.print(ass.mCount);
15564 pw.print(" times)");
15566 for (int i=0; i<ass.mStateTimes.length; i++) {
15567 long amt = ass.mStateTimes[i];
15568 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15569 amt += now - ass.mLastStateUptime;
15573 pw.print(ProcessList.makeProcStateString(
15574 i + ActivityManager.MIN_PROCESS_STATE));
15576 TimeUtils.formatDuration(amt, pw);
15577 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15583 if (ass.mNesting > 0) {
15584 pw.print(" Currently active: ");
15585 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15594 if (!printedAnything) {
15595 pw.println(" (nothing)");
15599 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15600 String header, boolean needSep) {
15601 boolean printed = false;
15602 int whichAppId = -1;
15603 if (dumpPackage != null) {
15605 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15607 whichAppId = UserHandle.getAppId(info.uid);
15608 } catch (NameNotFoundException e) {
15609 e.printStackTrace();
15612 for (int i=0; i<uids.size(); i++) {
15613 UidRecord uidRec = uids.valueAt(i);
15614 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15623 pw.println(header);
15626 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15627 pw.print(": "); pw.println(uidRec);
15632 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15633 int opti, boolean dumpAll, String dumpPackage) {
15634 boolean needSep = false;
15635 boolean printedAnything = false;
15638 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15641 final int NP = mProcessNames.getMap().size();
15642 for (int ip=0; ip<NP; ip++) {
15643 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15644 final int NA = procs.size();
15645 for (int ia=0; ia<NA; ia++) {
15646 ProcessRecord r = procs.valueAt(ia);
15647 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15651 pw.println(" All known processes:");
15653 printedAnything = true;
15655 pw.print(r.persistent ? " *PERS*" : " *APP*");
15656 pw.print(" UID "); pw.print(procs.keyAt(ia));
15657 pw.print(" "); pw.println(r);
15659 if (r.persistent) {
15666 if (mIsolatedProcesses.size() > 0) {
15667 boolean printed = false;
15668 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15669 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15670 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15677 pw.println(" Isolated process list (sorted by uid):");
15678 printedAnything = true;
15682 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15687 if (mActiveInstrumentation.size() > 0) {
15688 boolean printed = false;
15689 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15690 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15691 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15692 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15699 pw.println(" Active instrumentation:");
15700 printedAnything = true;
15704 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15710 if (mActiveUids.size() > 0) {
15711 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15712 printedAnything = needSep = true;
15716 if (mValidateUids.size() > 0) {
15717 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15718 printedAnything = needSep = true;
15723 if (mLruProcesses.size() > 0) {
15727 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15728 pw.print(" total, non-act at ");
15729 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15730 pw.print(", non-svc at ");
15731 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15733 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15735 printedAnything = true;
15738 if (dumpAll || dumpPackage != null) {
15739 synchronized (mPidsSelfLocked) {
15740 boolean printed = false;
15741 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15742 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15743 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15747 if (needSep) pw.println();
15749 pw.println(" PID mappings:");
15751 printedAnything = true;
15753 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15754 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15759 if (mImportantProcesses.size() > 0) {
15760 synchronized (mPidsSelfLocked) {
15761 boolean printed = false;
15762 for (int i = 0; i< mImportantProcesses.size(); i++) {
15763 ProcessRecord r = mPidsSelfLocked.get(
15764 mImportantProcesses.valueAt(i).pid);
15765 if (dumpPackage != null && (r == null
15766 || !r.pkgList.containsKey(dumpPackage))) {
15770 if (needSep) pw.println();
15772 pw.println(" Foreground Processes:");
15774 printedAnything = true;
15776 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15777 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15782 if (mPersistentStartingProcesses.size() > 0) {
15783 if (needSep) pw.println();
15785 printedAnything = true;
15786 pw.println(" Persisent processes that are starting:");
15787 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15788 "Starting Norm", "Restarting PERS", dumpPackage);
15791 if (mRemovedProcesses.size() > 0) {
15792 if (needSep) pw.println();
15794 printedAnything = true;
15795 pw.println(" Processes that are being removed:");
15796 dumpProcessList(pw, this, mRemovedProcesses, " ",
15797 "Removed Norm", "Removed PERS", dumpPackage);
15800 if (mProcessesOnHold.size() > 0) {
15801 if (needSep) pw.println();
15803 printedAnything = true;
15804 pw.println(" Processes that are on old until the system is ready:");
15805 dumpProcessList(pw, this, mProcessesOnHold, " ",
15806 "OnHold Norm", "OnHold PERS", dumpPackage);
15809 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15811 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15813 printedAnything = true;
15816 if (dumpPackage == null) {
15819 mUserController.dump(pw, dumpAll);
15821 if (mHomeProcess != null && (dumpPackage == null
15822 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15827 pw.println(" mHomeProcess: " + mHomeProcess);
15829 if (mPreviousProcess != null && (dumpPackage == null
15830 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15835 pw.println(" mPreviousProcess: " + mPreviousProcess);
15838 StringBuilder sb = new StringBuilder(128);
15839 sb.append(" mPreviousProcessVisibleTime: ");
15840 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15843 if (mHeavyWeightProcess != null && (dumpPackage == null
15844 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15849 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15851 if (dumpPackage == null) {
15852 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15853 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15856 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15857 if (mCompatModePackages.getPackages().size() > 0) {
15858 boolean printed = false;
15859 for (Map.Entry<String, Integer> entry
15860 : mCompatModePackages.getPackages().entrySet()) {
15861 String pkg = entry.getKey();
15862 int mode = entry.getValue();
15863 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15867 pw.println(" mScreenCompatPackages:");
15870 pw.print(" "); pw.print(pkg); pw.print(": ");
15871 pw.print(mode); pw.println();
15874 final int NI = mUidObservers.getRegisteredCallbackCount();
15875 boolean printed = false;
15876 for (int i=0; i<NI; i++) {
15877 final UidObserverRegistration reg = (UidObserverRegistration)
15878 mUidObservers.getRegisteredCallbackCookie(i);
15879 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15881 pw.println(" mUidObservers:");
15884 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15885 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15886 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15889 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15892 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15895 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15896 pw.print(" STATE");
15897 pw.print(" (cut="); pw.print(reg.cutpoint);
15901 if (reg.lastProcStates != null) {
15902 final int NJ = reg.lastProcStates.size();
15903 for (int j=0; j<NJ; j++) {
15904 pw.print(" Last ");
15905 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15906 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15911 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15912 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15913 if (mPendingTempWhitelist.size() > 0) {
15914 pw.println(" mPendingTempWhitelist:");
15915 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15916 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15918 UserHandle.formatUid(pw, ptw.targetUid);
15920 TimeUtils.formatDuration(ptw.duration, pw);
15922 pw.println(ptw.tag);
15926 if (dumpPackage == null) {
15927 pw.println(" mWakefulness="
15928 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15929 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
15930 pw.println(" mSleeping=" + mSleeping);
15931 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15932 if (mRunningVoice != null) {
15933 pw.println(" mRunningVoice=" + mRunningVoice);
15934 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15937 pw.println(" mVrController=" + mVrController);
15938 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15939 || mOrigWaitForDebugger) {
15940 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15941 || dumpPackage.equals(mOrigDebugApp)) {
15946 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15947 + " mDebugTransient=" + mDebugTransient
15948 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15951 if (mCurAppTimeTracker != null) {
15952 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15954 if (mMemWatchProcesses.getMap().size() > 0) {
15955 pw.println(" Mem watch processes:");
15956 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15957 = mMemWatchProcesses.getMap();
15958 for (int i=0; i<procs.size(); i++) {
15959 final String proc = procs.keyAt(i);
15960 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15961 for (int j=0; j<uids.size(); j++) {
15966 StringBuilder sb = new StringBuilder();
15967 sb.append(" ").append(proc).append('/');
15968 UserHandle.formatUid(sb, uids.keyAt(j));
15969 Pair<Long, String> val = uids.valueAt(j);
15970 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15971 if (val.second != null) {
15972 sb.append(", report to ").append(val.second);
15974 pw.println(sb.toString());
15977 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15978 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15979 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15980 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15982 if (mTrackAllocationApp != null) {
15983 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15988 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15991 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15992 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15993 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15998 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15999 if (mProfilerInfo != null) {
16000 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16001 mProfilerInfo.profileFd);
16002 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
16003 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16004 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16005 pw.println(" mProfileType=" + mProfileType);
16009 if (mNativeDebuggingApp != null) {
16010 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16015 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
16018 if (dumpPackage == null) {
16019 if (mAlwaysFinishActivities) {
16020 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16022 if (mController != null) {
16023 pw.println(" mController=" + mController
16024 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16027 pw.println(" Total persistent processes: " + numPers);
16028 pw.println(" mProcessesReady=" + mProcessesReady
16029 + " mSystemReady=" + mSystemReady
16030 + " mBooted=" + mBooted
16031 + " mFactoryTest=" + mFactoryTest);
16032 pw.println(" mBooting=" + mBooting
16033 + " mCallFinishBooting=" + mCallFinishBooting
16034 + " mBootAnimationComplete=" + mBootAnimationComplete);
16035 pw.print(" mLastPowerCheckUptime=");
16036 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16038 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16039 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16040 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16041 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
16042 + " (" + mLruProcesses.size() + " total)"
16043 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16044 + " mNumServiceProcs=" + mNumServiceProcs
16045 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16046 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
16047 + " mLastMemoryLevel=" + mLastMemoryLevel
16048 + " mLastNumProcesses=" + mLastNumProcesses);
16049 long now = SystemClock.uptimeMillis();
16050 pw.print(" mLastIdleTime=");
16051 TimeUtils.formatDuration(now, mLastIdleTime, pw);
16052 pw.print(" mLowRamSinceLastIdle=");
16053 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16058 if (!printedAnything) {
16059 pw.println(" (nothing)");
16063 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16064 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16065 if (mProcessesToGc.size() > 0) {
16066 boolean printed = false;
16067 long now = SystemClock.uptimeMillis();
16068 for (int i=0; i<mProcessesToGc.size(); i++) {
16069 ProcessRecord proc = mProcessesToGc.get(i);
16070 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16074 if (needSep) pw.println();
16076 pw.println(" Processes that are waiting to GC:");
16079 pw.print(" Process "); pw.println(proc);
16080 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16081 pw.print(", last gced=");
16082 pw.print(now-proc.lastRequestedGc);
16083 pw.print(" ms ago, last lowMem=");
16084 pw.print(now-proc.lastLowMemory);
16085 pw.println(" ms ago");
16092 void printOomLevel(PrintWriter pw, String name, int adj) {
16096 if (adj < 10) pw.print(' ');
16098 if (adj > -10) pw.print(' ');
16104 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16108 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16109 int opti, boolean dumpAll) {
16110 boolean needSep = false;
16112 if (mLruProcesses.size() > 0) {
16113 if (needSep) pw.println();
16115 pw.println(" OOM levels:");
16116 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16117 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16118 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16119 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16120 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16121 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16122 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16123 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16124 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16125 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16126 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16127 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16128 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16129 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16131 if (needSep) pw.println();
16132 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16133 pw.print(" total, non-act at ");
16134 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16135 pw.print(", non-svc at ");
16136 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16138 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16142 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16145 pw.println(" mHomeProcess: " + mHomeProcess);
16146 pw.println(" mPreviousProcess: " + mPreviousProcess);
16147 if (mHeavyWeightProcess != null) {
16148 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16155 * There are three ways to call this:
16156 * - no provider specified: dump all the providers
16157 * - a flattened component name that matched an existing provider was specified as the
16158 * first arg: dump that one provider
16159 * - the first arg isn't the flattened component name of an existing provider:
16160 * dump all providers whose component contains the first arg as a substring
16162 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16163 int opti, boolean dumpAll) {
16164 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16167 static class ItemMatcher {
16168 ArrayList<ComponentName> components;
16169 ArrayList<String> strings;
16170 ArrayList<Integer> objects;
16177 void build(String name) {
16178 ComponentName componentName = ComponentName.unflattenFromString(name);
16179 if (componentName != null) {
16180 if (components == null) {
16181 components = new ArrayList<ComponentName>();
16183 components.add(componentName);
16187 // Not a '/' separated full component name; maybe an object ID?
16189 objectId = Integer.parseInt(name, 16);
16190 if (objects == null) {
16191 objects = new ArrayList<Integer>();
16193 objects.add(objectId);
16195 } catch (RuntimeException e) {
16196 // Not an integer; just do string match.
16197 if (strings == null) {
16198 strings = new ArrayList<String>();
16206 int build(String[] args, int opti) {
16207 for (; opti<args.length; opti++) {
16208 String name = args[opti];
16209 if ("--".equals(name)) {
16217 boolean match(Object object, ComponentName comp) {
16221 if (components != null) {
16222 for (int i=0; i<components.size(); i++) {
16223 if (components.get(i).equals(comp)) {
16228 if (objects != null) {
16229 for (int i=0; i<objects.size(); i++) {
16230 if (System.identityHashCode(object) == objects.get(i)) {
16235 if (strings != null) {
16236 String flat = comp.flattenToString();
16237 for (int i=0; i<strings.size(); i++) {
16238 if (flat.contains(strings.get(i))) {
16248 * There are three things that cmd can be:
16249 * - a flattened component name that matches an existing activity
16250 * - the cmd arg isn't the flattened component name of an existing activity:
16251 * dump all activity whose component contains the cmd as a substring
16252 * - A hex number of the ActivityRecord object instance.
16254 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16255 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16257 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16258 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16259 ArrayList<ActivityRecord> activities;
16261 synchronized (this) {
16262 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16263 dumpFocusedStackOnly);
16266 if (activities.size() <= 0) {
16270 String[] newArgs = new String[args.length - opti];
16271 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16273 TaskRecord lastTask = null;
16274 boolean needSep = false;
16275 for (int i=activities.size()-1; i>=0; i--) {
16276 ActivityRecord r = activities.get(i);
16281 synchronized (this) {
16282 final TaskRecord task = r.getTask();
16283 if (lastTask != task) {
16285 pw.print("TASK "); pw.print(lastTask.affinity);
16286 pw.print(" id="); pw.print(lastTask.taskId);
16287 pw.print(" userId="); pw.println(lastTask.userId);
16289 lastTask.dump(pw, " ");
16293 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16299 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16300 * there is a thread associated with the activity.
16302 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16303 final ActivityRecord r, String[] args, boolean dumpAll) {
16304 String innerPrefix = prefix + " ";
16305 synchronized (this) {
16306 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16307 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16309 if (r.app != null) pw.println(r.app.pid);
16310 else pw.println("(not running)");
16312 r.dump(pw, innerPrefix);
16315 if (r.app != null && r.app.thread != null) {
16316 // flush anything that is already in the PrintWriter since the thread is going
16317 // to write to the file descriptor directly
16320 TransferPipe tp = new TransferPipe();
16322 r.app.thread.dumpActivity(tp.getWriteFd(),
16323 r.appToken, innerPrefix, args);
16328 } catch (IOException e) {
16329 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16330 } catch (RemoteException e) {
16331 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16336 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16337 int opti, boolean dumpAll, String dumpPackage) {
16338 boolean needSep = false;
16339 boolean onlyHistory = false;
16340 boolean printedAnything = false;
16342 if ("history".equals(dumpPackage)) {
16343 if (opti < args.length && "-s".equals(args[opti])) {
16346 onlyHistory = true;
16347 dumpPackage = null;
16350 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16351 if (!onlyHistory && dumpAll) {
16352 if (mRegisteredReceivers.size() > 0) {
16353 boolean printed = false;
16354 Iterator it = mRegisteredReceivers.values().iterator();
16355 while (it.hasNext()) {
16356 ReceiverList r = (ReceiverList)it.next();
16357 if (dumpPackage != null && (r.app == null ||
16358 !dumpPackage.equals(r.app.info.packageName))) {
16362 pw.println(" Registered Receivers:");
16365 printedAnything = true;
16367 pw.print(" * "); pw.println(r);
16372 if (mReceiverResolver.dump(pw, needSep ?
16373 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16374 " ", dumpPackage, false, false)) {
16376 printedAnything = true;
16380 for (BroadcastQueue q : mBroadcastQueues) {
16381 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16382 printedAnything |= needSep;
16387 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16388 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16393 printedAnything = true;
16394 pw.print(" Sticky broadcasts for user ");
16395 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16396 StringBuilder sb = new StringBuilder(128);
16397 for (Map.Entry<String, ArrayList<Intent>> ent
16398 : mStickyBroadcasts.valueAt(user).entrySet()) {
16399 pw.print(" * Sticky action "); pw.print(ent.getKey());
16402 ArrayList<Intent> intents = ent.getValue();
16403 final int N = intents.size();
16404 for (int i=0; i<N; i++) {
16406 sb.append(" Intent: ");
16407 intents.get(i).toShortString(sb, false, true, false, false);
16408 pw.println(sb.toString());
16409 Bundle bundle = intents.get(i).getExtras();
16410 if (bundle != null) {
16412 pw.println(bundle.toString());
16422 if (!onlyHistory && dumpAll) {
16424 for (BroadcastQueue queue : mBroadcastQueues) {
16425 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16426 + queue.mBroadcastsScheduled);
16428 pw.println(" mHandler:");
16429 mHandler.dump(new PrintWriterPrinter(pw), " ");
16431 printedAnything = true;
16434 if (!printedAnything) {
16435 pw.println(" (nothing)");
16439 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16440 int opti, boolean dumpAll, String dumpPackage) {
16441 if (mCurBroadcastStats == null) {
16445 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16446 final long now = SystemClock.elapsedRealtime();
16447 if (mLastBroadcastStats != null) {
16448 pw.print(" Last stats (from ");
16449 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16451 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16453 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16454 - mLastBroadcastStats.mStartUptime, pw);
16455 pw.println(" uptime):");
16456 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16457 pw.println(" (nothing)");
16461 pw.print(" Current stats (from ");
16462 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16463 pw.print(" to now, ");
16464 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16465 - mCurBroadcastStats.mStartUptime, pw);
16466 pw.println(" uptime):");
16467 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16468 pw.println(" (nothing)");
16472 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16473 int opti, boolean fullCheckin, String dumpPackage) {
16474 if (mCurBroadcastStats == null) {
16478 if (mLastBroadcastStats != null) {
16479 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16481 mLastBroadcastStats = null;
16485 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16487 mCurBroadcastStats = null;
16491 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16492 int opti, boolean dumpAll, String dumpPackage) {
16494 boolean printedAnything = false;
16496 ItemMatcher matcher = new ItemMatcher();
16497 matcher.build(args, opti);
16499 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16501 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16502 printedAnything |= needSep;
16504 if (mLaunchingProviders.size() > 0) {
16505 boolean printed = false;
16506 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16507 ContentProviderRecord r = mLaunchingProviders.get(i);
16508 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16512 if (needSep) pw.println();
16514 pw.println(" Launching content providers:");
16516 printedAnything = true;
16518 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16523 if (!printedAnything) {
16524 pw.println(" (nothing)");
16528 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16529 int opti, boolean dumpAll, String dumpPackage) {
16530 boolean needSep = false;
16531 boolean printedAnything = false;
16533 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16535 if (mGrantedUriPermissions.size() > 0) {
16536 boolean printed = false;
16538 if (dumpPackage != null) {
16540 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16541 MATCH_ANY_USER, 0);
16542 } catch (NameNotFoundException e) {
16546 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16547 int uid = mGrantedUriPermissions.keyAt(i);
16548 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16551 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16553 if (needSep) pw.println();
16555 pw.println(" Granted Uri Permissions:");
16557 printedAnything = true;
16559 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16560 for (UriPermission perm : perms.values()) {
16561 pw.print(" "); pw.println(perm);
16563 perm.dump(pw, " ");
16569 if (!printedAnything) {
16570 pw.println(" (nothing)");
16574 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16575 int opti, boolean dumpAll, String dumpPackage) {
16576 boolean printed = false;
16578 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16580 if (mIntentSenderRecords.size() > 0) {
16581 // Organize these by package name, so they are easier to read.
16582 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16583 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16584 final Iterator<WeakReference<PendingIntentRecord>> it
16585 = mIntentSenderRecords.values().iterator();
16586 while (it.hasNext()) {
16587 WeakReference<PendingIntentRecord> ref = it.next();
16588 PendingIntentRecord rec = ref != null ? ref.get() : null;
16593 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16596 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16597 if (list == null) {
16598 list = new ArrayList<>();
16599 byPackage.put(rec.key.packageName, list);
16603 for (int i = 0; i < byPackage.size(); i++) {
16604 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16606 pw.print(" * "); pw.print(byPackage.keyAt(i));
16607 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16608 for (int j = 0; j < intents.size(); j++) {
16609 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16611 intents.get(j).dump(pw, " ");
16615 if (weakRefs.size() > 0) {
16617 pw.println(" * WEAK REFS:");
16618 for (int i = 0; i < weakRefs.size(); i++) {
16619 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16625 pw.println(" (nothing)");
16629 private static final int dumpProcessList(PrintWriter pw,
16630 ActivityManagerService service, List list,
16631 String prefix, String normalLabel, String persistentLabel,
16632 String dumpPackage) {
16634 final int N = list.size()-1;
16635 for (int i=N; i>=0; i--) {
16636 ProcessRecord r = (ProcessRecord)list.get(i);
16637 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16640 pw.println(String.format("%s%s #%2d: %s",
16641 prefix, (r.persistent ? persistentLabel : normalLabel),
16643 if (r.persistent) {
16650 private static final boolean dumpProcessOomList(PrintWriter pw,
16651 ActivityManagerService service, List<ProcessRecord> origList,
16652 String prefix, String normalLabel, String persistentLabel,
16653 boolean inclDetails, String dumpPackage) {
16655 ArrayList<Pair<ProcessRecord, Integer>> list
16656 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16657 for (int i=0; i<origList.size(); i++) {
16658 ProcessRecord r = origList.get(i);
16659 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16662 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16665 if (list.size() <= 0) {
16669 Comparator<Pair<ProcessRecord, Integer>> comparator
16670 = new Comparator<Pair<ProcessRecord, Integer>>() {
16672 public int compare(Pair<ProcessRecord, Integer> object1,
16673 Pair<ProcessRecord, Integer> object2) {
16674 if (object1.first.setAdj != object2.first.setAdj) {
16675 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16677 if (object1.first.setProcState != object2.first.setProcState) {
16678 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16680 if (object1.second.intValue() != object2.second.intValue()) {
16681 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16687 Collections.sort(list, comparator);
16689 final long curUptime = SystemClock.uptimeMillis();
16690 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16692 for (int i=list.size()-1; i>=0; i--) {
16693 ProcessRecord r = list.get(i).first;
16694 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16696 switch (r.setSchedGroup) {
16697 case ProcessList.SCHED_GROUP_BACKGROUND:
16700 case ProcessList.SCHED_GROUP_DEFAULT:
16703 case ProcessList.SCHED_GROUP_TOP_APP:
16711 if (r.foregroundActivities) {
16713 } else if (r.foregroundServices) {
16718 String procState = ProcessList.makeProcStateString(r.curProcState);
16720 pw.print(r.persistent ? persistentLabel : normalLabel);
16722 int num = (origList.size()-1)-list.get(i).second;
16723 if (num < 10) pw.print(' ');
16728 pw.print(schedGroup);
16730 pw.print(foreground);
16732 pw.print(procState);
16734 if (r.trimMemoryLevel < 10) pw.print(' ');
16735 pw.print(r.trimMemoryLevel);
16737 pw.print(r.toShortString());
16739 pw.print(r.adjType);
16741 if (r.adjSource != null || r.adjTarget != null) {
16744 if (r.adjTarget instanceof ComponentName) {
16745 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16746 } else if (r.adjTarget != null) {
16747 pw.print(r.adjTarget.toString());
16749 pw.print("{null}");
16752 if (r.adjSource instanceof ProcessRecord) {
16754 pw.print(((ProcessRecord)r.adjSource).toShortString());
16756 } else if (r.adjSource != null) {
16757 pw.println(r.adjSource.toString());
16759 pw.println("{null}");
16765 pw.print("oom: max="); pw.print(r.maxAdj);
16766 pw.print(" curRaw="); pw.print(r.curRawAdj);
16767 pw.print(" setRaw="); pw.print(r.setRawAdj);
16768 pw.print(" cur="); pw.print(r.curAdj);
16769 pw.print(" set="); pw.println(r.setAdj);
16772 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16773 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16774 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16775 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16776 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16780 pw.print("cached="); pw.print(r.cached);
16781 pw.print(" empty="); pw.print(r.empty);
16782 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16784 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16785 if (r.lastCpuTime != 0) {
16786 long timeUsed = r.curCpuTime - r.lastCpuTime;
16789 pw.print("run cpu over ");
16790 TimeUtils.formatDuration(uptimeSince, pw);
16791 pw.print(" used ");
16792 TimeUtils.formatDuration(timeUsed, pw);
16794 pw.print((timeUsed*100)/uptimeSince);
16803 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16805 ArrayList<ProcessRecord> procs;
16806 synchronized (this) {
16807 if (args != null && args.length > start
16808 && args[start].charAt(0) != '-') {
16809 procs = new ArrayList<ProcessRecord>();
16812 pid = Integer.parseInt(args[start]);
16813 } catch (NumberFormatException e) {
16815 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16816 ProcessRecord proc = mLruProcesses.get(i);
16817 if (proc.pid == pid) {
16819 } else if (allPkgs && proc.pkgList != null
16820 && proc.pkgList.containsKey(args[start])) {
16822 } else if (proc.processName.equals(args[start])) {
16826 if (procs.size() <= 0) {
16830 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16836 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16837 PrintWriter pw, String[] args) {
16838 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16839 if (procs == null) {
16840 pw.println("No process found for: " + args[0]);
16844 long uptime = SystemClock.uptimeMillis();
16845 long realtime = SystemClock.elapsedRealtime();
16846 pw.println("Applications Graphics Acceleration Info:");
16847 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16849 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16850 ProcessRecord r = procs.get(i);
16851 if (r.thread != null) {
16852 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16855 TransferPipe tp = new TransferPipe();
16857 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16862 } catch (IOException e) {
16863 pw.println("Failure while dumping the app: " + r);
16865 } catch (RemoteException e) {
16866 pw.println("Got a RemoteException while dumping the app " + r);
16873 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16874 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16875 if (procs == null) {
16876 pw.println("No process found for: " + args[0]);
16880 pw.println("Applications Database Info:");
16882 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16883 ProcessRecord r = procs.get(i);
16884 if (r.thread != null) {
16885 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16888 TransferPipe tp = new TransferPipe();
16890 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16895 } catch (IOException e) {
16896 pw.println("Failure while dumping the app: " + r);
16898 } catch (RemoteException e) {
16899 pw.println("Got a RemoteException while dumping the app " + r);
16906 final static class MemItem {
16907 final boolean isProc;
16908 final String label;
16909 final String shortLabel;
16911 final long swapPss;
16913 final boolean hasActivities;
16914 ArrayList<MemItem> subitems;
16916 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16917 boolean _hasActivities) {
16920 shortLabel = _shortLabel;
16922 swapPss = _swapPss;
16924 hasActivities = _hasActivities;
16927 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16930 shortLabel = _shortLabel;
16932 swapPss = _swapPss;
16934 hasActivities = false;
16938 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16939 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16940 if (sort && !isCompact) {
16941 Collections.sort(items, new Comparator<MemItem>() {
16943 public int compare(MemItem lhs, MemItem rhs) {
16944 if (lhs.pss < rhs.pss) {
16946 } else if (lhs.pss > rhs.pss) {
16954 for (int i=0; i<items.size(); i++) {
16955 MemItem mi = items.get(i);
16958 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16959 mi.label, stringifyKBSize(mi.swapPss));
16961 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16963 } else if (mi.isProc) {
16964 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16965 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16966 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16967 pw.println(mi.hasActivities ? ",a" : ",e");
16969 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16970 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16972 if (mi.subitems != null) {
16973 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16974 true, isCompact, dumpSwapPss);
16979 // These are in KB.
16980 static final long[] DUMP_MEM_BUCKETS = new long[] {
16981 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16982 120*1024, 160*1024, 200*1024,
16983 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16984 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16987 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16988 boolean stackLike) {
16989 int start = label.lastIndexOf('.');
16990 if (start >= 0) start++;
16992 int end = label.length();
16993 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16994 if (DUMP_MEM_BUCKETS[i] >= memKB) {
16995 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16996 out.append(bucket);
16997 out.append(stackLike ? "MB." : "MB ");
16998 out.append(label, start, end);
17002 out.append(memKB/1024);
17003 out.append(stackLike ? "MB." : "MB ");
17004 out.append(label, start, end);
17007 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17008 ProcessList.NATIVE_ADJ,
17009 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17010 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17011 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17012 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17013 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17014 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17016 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17018 "System", "Persistent", "Persistent Service", "Foreground",
17019 "Visible", "Perceptible",
17020 "Heavy Weight", "Backup",
17021 "A Services", "Home",
17022 "Previous", "B Services", "Cached"
17024 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17026 "sys", "pers", "persvc", "fore",
17029 "servicea", "home",
17030 "prev", "serviceb", "cached"
17033 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17034 long realtime, boolean isCheckinRequest, boolean isCompact) {
17036 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17038 if (isCheckinRequest || isCompact) {
17039 // short checkin version
17040 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17042 pw.println("Applications Memory Usage (in Kilobytes):");
17043 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17047 private static final int KSM_SHARED = 0;
17048 private static final int KSM_SHARING = 1;
17049 private static final int KSM_UNSHARED = 2;
17050 private static final int KSM_VOLATILE = 3;
17052 private final long[] getKsmInfo() {
17053 long[] longOut = new long[4];
17054 final int[] SINGLE_LONG_FORMAT = new int[] {
17055 PROC_SPACE_TERM| PROC_OUT_LONG
17057 long[] longTmp = new long[1];
17058 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17059 SINGLE_LONG_FORMAT, null, longTmp, null);
17060 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17062 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17063 SINGLE_LONG_FORMAT, null, longTmp, null);
17064 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17066 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17067 SINGLE_LONG_FORMAT, null, longTmp, null);
17068 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17070 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17071 SINGLE_LONG_FORMAT, null, longTmp, null);
17072 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17076 private static String stringifySize(long size, int order) {
17077 Locale locale = Locale.US;
17080 return String.format(locale, "%,13d", size);
17082 return String.format(locale, "%,9dK", size / 1024);
17084 return String.format(locale, "%,5dM", size / 1024 / 1024);
17085 case 1024 * 1024 * 1024:
17086 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17088 throw new IllegalArgumentException("Invalid size order");
17092 private static String stringifyKBSize(long size) {
17093 return stringifySize(size * 1024, 1024);
17096 // Update this version number in case you change the 'compact' format
17097 private static final int MEMINFO_COMPACT_VERSION = 1;
17099 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17100 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17101 boolean dumpDetails = false;
17102 boolean dumpFullDetails = false;
17103 boolean dumpDalvik = false;
17104 boolean dumpSummaryOnly = false;
17105 boolean dumpUnreachable = false;
17106 boolean oomOnly = false;
17107 boolean isCompact = false;
17108 boolean localOnly = false;
17109 boolean packages = false;
17110 boolean isCheckinRequest = false;
17111 boolean dumpSwapPss = false;
17114 while (opti < args.length) {
17115 String opt = args[opti];
17116 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17120 if ("-a".equals(opt)) {
17121 dumpDetails = true;
17122 dumpFullDetails = true;
17124 dumpSwapPss = true;
17125 } else if ("-d".equals(opt)) {
17127 } else if ("-c".equals(opt)) {
17129 } else if ("-s".equals(opt)) {
17130 dumpDetails = true;
17131 dumpSummaryOnly = true;
17132 } else if ("-S".equals(opt)) {
17133 dumpSwapPss = true;
17134 } else if ("--unreachable".equals(opt)) {
17135 dumpUnreachable = true;
17136 } else if ("--oom".equals(opt)) {
17138 } else if ("--local".equals(opt)) {
17140 } else if ("--package".equals(opt)) {
17142 } else if ("--checkin".equals(opt)) {
17143 isCheckinRequest = true;
17145 } else if ("-h".equals(opt)) {
17146 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17147 pw.println(" -a: include all available information for each process.");
17148 pw.println(" -d: include dalvik details.");
17149 pw.println(" -c: dump in a compact machine-parseable representation.");
17150 pw.println(" -s: dump only summary of application memory usage.");
17151 pw.println(" -S: dump also SwapPss.");
17152 pw.println(" --oom: only show processes organized by oom adj.");
17153 pw.println(" --local: only collect details locally, don't call process.");
17154 pw.println(" --package: interpret process arg as package, dumping all");
17155 pw.println(" processes that have loaded that package.");
17156 pw.println(" --checkin: dump data for a checkin");
17157 pw.println("If [process] is specified it can be the name or ");
17158 pw.println("pid of a specific process to dump.");
17161 pw.println("Unknown argument: " + opt + "; use -h for help");
17165 long uptime = SystemClock.uptimeMillis();
17166 long realtime = SystemClock.elapsedRealtime();
17167 final long[] tmpLong = new long[1];
17169 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17170 if (procs == null) {
17171 // No Java processes. Maybe they want to print a native process.
17172 if (args != null && args.length > opti
17173 && args[opti].charAt(0) != '-') {
17174 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17175 = new ArrayList<ProcessCpuTracker.Stats>();
17176 updateCpuStatsNow();
17179 findPid = Integer.parseInt(args[opti]);
17180 } catch (NumberFormatException e) {
17182 synchronized (mProcessCpuTracker) {
17183 final int N = mProcessCpuTracker.countStats();
17184 for (int i=0; i<N; i++) {
17185 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17186 if (st.pid == findPid || (st.baseName != null
17187 && st.baseName.equals(args[opti]))) {
17188 nativeProcs.add(st);
17192 if (nativeProcs.size() > 0) {
17193 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17195 Debug.MemoryInfo mi = null;
17196 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17197 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17198 final int pid = r.pid;
17199 if (!isCheckinRequest && dumpDetails) {
17200 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17203 mi = new Debug.MemoryInfo();
17205 if (dumpDetails || (!brief && !oomOnly)) {
17206 Debug.getMemoryInfo(pid, mi);
17208 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17209 mi.dalvikPrivateDirty = (int)tmpLong[0];
17211 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17212 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17213 if (isCheckinRequest) {
17220 pw.println("No process found for: " + args[opti]);
17224 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17225 dumpDetails = true;
17228 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17230 String[] innerArgs = new String[args.length-opti];
17231 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17233 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17234 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17235 long nativePss = 0;
17236 long nativeSwapPss = 0;
17237 long dalvikPss = 0;
17238 long dalvikSwapPss = 0;
17239 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17241 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17244 long otherSwapPss = 0;
17245 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17246 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17248 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17249 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17250 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17251 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17254 long totalSwapPss = 0;
17255 long cachedPss = 0;
17256 long cachedSwapPss = 0;
17257 boolean hasSwapPss = false;
17259 Debug.MemoryInfo mi = null;
17260 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17261 final ProcessRecord r = procs.get(i);
17262 final IApplicationThread thread;
17265 final boolean hasActivities;
17266 synchronized (this) {
17269 oomAdj = r.getSetAdjWithServices();
17270 hasActivities = r.activities.size() > 0;
17272 if (thread != null) {
17273 if (!isCheckinRequest && dumpDetails) {
17274 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17277 mi = new Debug.MemoryInfo();
17279 if (dumpDetails || (!brief && !oomOnly)) {
17280 Debug.getMemoryInfo(pid, mi);
17281 hasSwapPss = mi.hasSwappedOutPss;
17283 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17284 mi.dalvikPrivateDirty = (int)tmpLong[0];
17288 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17289 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17290 if (isCheckinRequest) {
17296 TransferPipe tp = new TransferPipe();
17298 thread.dumpMemInfo(tp.getWriteFd(),
17299 mi, isCheckinRequest, dumpFullDetails,
17300 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17305 } catch (IOException e) {
17306 if (!isCheckinRequest) {
17307 pw.println("Got IoException! " + e);
17310 } catch (RemoteException e) {
17311 if (!isCheckinRequest) {
17312 pw.println("Got RemoteException! " + e);
17319 final long myTotalPss = mi.getTotalPss();
17320 final long myTotalUss = mi.getTotalUss();
17321 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17323 synchronized (this) {
17324 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17325 // Record this for posterity if the process has been stable.
17326 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17330 if (!isCheckinRequest && mi != null) {
17331 totalPss += myTotalPss;
17332 totalSwapPss += myTotalSwapPss;
17333 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17334 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17335 myTotalSwapPss, pid, hasActivities);
17336 procMems.add(pssItem);
17337 procMemsMap.put(pid, pssItem);
17339 nativePss += mi.nativePss;
17340 nativeSwapPss += mi.nativeSwappedOutPss;
17341 dalvikPss += mi.dalvikPss;
17342 dalvikSwapPss += mi.dalvikSwappedOutPss;
17343 for (int j=0; j<dalvikSubitemPss.length; j++) {
17344 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17345 dalvikSubitemSwapPss[j] +=
17346 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17348 otherPss += mi.otherPss;
17349 otherSwapPss += mi.otherSwappedOutPss;
17350 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17351 long mem = mi.getOtherPss(j);
17354 mem = mi.getOtherSwappedOutPss(j);
17355 miscSwapPss[j] += mem;
17356 otherSwapPss -= mem;
17359 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17360 cachedPss += myTotalPss;
17361 cachedSwapPss += myTotalSwapPss;
17364 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17365 if (oomIndex == (oomPss.length - 1)
17366 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17367 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17368 oomPss[oomIndex] += myTotalPss;
17369 oomSwapPss[oomIndex] += myTotalSwapPss;
17370 if (oomProcs[oomIndex] == null) {
17371 oomProcs[oomIndex] = new ArrayList<MemItem>();
17373 oomProcs[oomIndex].add(pssItem);
17381 long nativeProcTotalPss = 0;
17383 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17384 // If we are showing aggregations, also look for native processes to
17385 // include so that our aggregations are more accurate.
17386 updateCpuStatsNow();
17388 synchronized (mProcessCpuTracker) {
17389 final int N = mProcessCpuTracker.countStats();
17390 for (int i=0; i<N; i++) {
17391 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17392 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17394 mi = new Debug.MemoryInfo();
17396 if (!brief && !oomOnly) {
17397 Debug.getMemoryInfo(st.pid, mi);
17399 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17400 mi.nativePrivateDirty = (int)tmpLong[0];
17403 final long myTotalPss = mi.getTotalPss();
17404 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17405 totalPss += myTotalPss;
17406 nativeProcTotalPss += myTotalPss;
17408 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17409 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17410 procMems.add(pssItem);
17412 nativePss += mi.nativePss;
17413 nativeSwapPss += mi.nativeSwappedOutPss;
17414 dalvikPss += mi.dalvikPss;
17415 dalvikSwapPss += mi.dalvikSwappedOutPss;
17416 for (int j=0; j<dalvikSubitemPss.length; j++) {
17417 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17418 dalvikSubitemSwapPss[j] +=
17419 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17421 otherPss += mi.otherPss;
17422 otherSwapPss += mi.otherSwappedOutPss;
17423 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17424 long mem = mi.getOtherPss(j);
17427 mem = mi.getOtherSwappedOutPss(j);
17428 miscSwapPss[j] += mem;
17429 otherSwapPss -= mem;
17431 oomPss[0] += myTotalPss;
17432 oomSwapPss[0] += myTotalSwapPss;
17433 if (oomProcs[0] == null) {
17434 oomProcs[0] = new ArrayList<MemItem>();
17436 oomProcs[0].add(pssItem);
17441 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17443 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17444 final int dalvikId = -2;
17445 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17446 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17447 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17448 String label = Debug.MemoryInfo.getOtherLabel(j);
17449 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17451 if (dalvikSubitemPss.length > 0) {
17452 // Add dalvik subitems.
17453 for (MemItem memItem : catMems) {
17454 int memItemStart = 0, memItemEnd = 0;
17455 if (memItem.id == dalvikId) {
17456 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17457 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17458 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17459 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17460 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17461 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17462 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17463 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17464 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17465 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17466 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17468 continue; // No subitems, continue.
17470 memItem.subitems = new ArrayList<MemItem>();
17471 for (int j=memItemStart; j<=memItemEnd; j++) {
17472 final String name = Debug.MemoryInfo.getOtherLabel(
17473 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17474 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17475 dalvikSubitemSwapPss[j], j));
17480 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17481 for (int j=0; j<oomPss.length; j++) {
17482 if (oomPss[j] != 0) {
17483 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17484 : DUMP_MEM_OOM_LABEL[j];
17485 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17486 DUMP_MEM_OOM_ADJ[j]);
17487 item.subitems = oomProcs[j];
17492 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17493 if (!brief && !oomOnly && !isCompact) {
17495 pw.println("Total PSS by process:");
17496 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17500 pw.println("Total PSS by OOM adjustment:");
17502 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17503 if (!brief && !oomOnly) {
17504 PrintWriter out = categoryPw != null ? categoryPw : pw;
17507 out.println("Total PSS by category:");
17509 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17514 MemInfoReader memInfo = new MemInfoReader();
17515 memInfo.readMemInfo();
17516 if (nativeProcTotalPss > 0) {
17517 synchronized (this) {
17518 final long cachedKb = memInfo.getCachedSizeKb();
17519 final long freeKb = memInfo.getFreeSizeKb();
17520 final long zramKb = memInfo.getZramTotalSizeKb();
17521 final long kernelKb = memInfo.getKernelUsedSizeKb();
17522 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17523 kernelKb*1024, nativeProcTotalPss*1024);
17524 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17525 nativeProcTotalPss);
17530 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17531 pw.print(" (status ");
17532 switch (mLastMemoryLevel) {
17533 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17534 pw.println("normal)");
17536 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17537 pw.println("moderate)");
17539 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17540 pw.println("low)");
17542 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17543 pw.println("critical)");
17546 pw.print(mLastMemoryLevel);
17550 pw.print(" Free RAM: ");
17551 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17552 + memInfo.getFreeSizeKb()));
17554 pw.print(stringifyKBSize(cachedPss));
17555 pw.print(" cached pss + ");
17556 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17557 pw.print(" cached kernel + ");
17558 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17559 pw.println(" free)");
17561 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17562 pw.print(cachedPss + memInfo.getCachedSizeKb()
17563 + memInfo.getFreeSizeKb()); pw.print(",");
17564 pw.println(totalPss - cachedPss);
17567 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17568 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17569 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17571 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17572 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17573 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17574 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17575 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17577 pw.print("lostram,"); pw.println(lostRAM);
17580 if (memInfo.getZramTotalSizeKb() != 0) {
17582 pw.print(" ZRAM: ");
17583 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17584 pw.print(" physical used for ");
17585 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17586 - memInfo.getSwapFreeSizeKb()));
17587 pw.print(" in swap (");
17588 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17589 pw.println(" total swap)");
17591 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17592 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17593 pw.println(memInfo.getSwapFreeSizeKb());
17596 final long[] ksm = getKsmInfo();
17598 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17599 || ksm[KSM_VOLATILE] != 0) {
17600 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17601 pw.print(" saved from shared ");
17602 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17603 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17604 pw.print(" unshared; ");
17605 pw.print(stringifyKBSize(
17606 ksm[KSM_VOLATILE])); pw.println(" volatile");
17608 pw.print(" Tuning: ");
17609 pw.print(ActivityManager.staticGetMemoryClass());
17610 pw.print(" (large ");
17611 pw.print(ActivityManager.staticGetLargeMemoryClass());
17612 pw.print("), oom ");
17613 pw.print(stringifySize(
17614 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17615 pw.print(", restore limit ");
17616 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17617 if (ActivityManager.isLowRamDeviceStatic()) {
17618 pw.print(" (low-ram)");
17620 if (ActivityManager.isHighEndGfx()) {
17621 pw.print(" (high-end-gfx)");
17625 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17626 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17627 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17628 pw.print("tuning,");
17629 pw.print(ActivityManager.staticGetMemoryClass());
17631 pw.print(ActivityManager.staticGetLargeMemoryClass());
17633 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17634 if (ActivityManager.isLowRamDeviceStatic()) {
17635 pw.print(",low-ram");
17637 if (ActivityManager.isHighEndGfx()) {
17638 pw.print(",high-end-gfx");
17646 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17647 long memtrack, String name) {
17649 sb.append(ProcessList.makeOomAdjString(oomAdj));
17651 sb.append(ProcessList.makeProcStateString(procState));
17653 ProcessList.appendRamKb(sb, pss);
17656 if (memtrack > 0) {
17658 sb.append(stringifyKBSize(memtrack));
17659 sb.append(" memtrack)");
17663 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17664 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17665 sb.append(" (pid ");
17668 sb.append(mi.adjType);
17670 if (mi.adjReason != null) {
17672 sb.append(mi.adjReason);
17677 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17678 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17679 for (int i=0, N=memInfos.size(); i<N; i++) {
17680 ProcessMemInfo mi = memInfos.get(i);
17681 infoMap.put(mi.pid, mi);
17683 updateCpuStatsNow();
17684 long[] memtrackTmp = new long[1];
17685 final List<ProcessCpuTracker.Stats> stats;
17686 // Get a list of Stats that have vsize > 0
17687 synchronized (mProcessCpuTracker) {
17688 stats = mProcessCpuTracker.getStats((st) -> {
17689 return st.vsize > 0;
17692 final int statsCount = stats.size();
17693 for (int i = 0; i < statsCount; i++) {
17694 ProcessCpuTracker.Stats st = stats.get(i);
17695 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17697 if (infoMap.indexOfKey(st.pid) < 0) {
17698 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17699 ProcessList.NATIVE_ADJ, -1, "native", null);
17701 mi.memtrack = memtrackTmp[0];
17708 long totalMemtrack = 0;
17709 for (int i=0, N=memInfos.size(); i<N; i++) {
17710 ProcessMemInfo mi = memInfos.get(i);
17712 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17713 mi.memtrack = memtrackTmp[0];
17715 totalPss += mi.pss;
17716 totalMemtrack += mi.memtrack;
17718 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17719 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17720 if (lhs.oomAdj != rhs.oomAdj) {
17721 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17723 if (lhs.pss != rhs.pss) {
17724 return lhs.pss < rhs.pss ? 1 : -1;
17730 StringBuilder tag = new StringBuilder(128);
17731 StringBuilder stack = new StringBuilder(128);
17732 tag.append("Low on memory -- ");
17733 appendMemBucket(tag, totalPss, "total", false);
17734 appendMemBucket(stack, totalPss, "total", true);
17736 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17737 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17738 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17740 boolean firstLine = true;
17741 int lastOomAdj = Integer.MIN_VALUE;
17742 long extraNativeRam = 0;
17743 long extraNativeMemtrack = 0;
17744 long cachedPss = 0;
17745 for (int i=0, N=memInfos.size(); i<N; i++) {
17746 ProcessMemInfo mi = memInfos.get(i);
17748 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17749 cachedPss += mi.pss;
17752 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17753 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17754 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17755 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17756 if (lastOomAdj != mi.oomAdj) {
17757 lastOomAdj = mi.oomAdj;
17758 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17761 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17766 stack.append("\n\t at ");
17774 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17775 appendMemBucket(tag, mi.pss, mi.name, false);
17777 appendMemBucket(stack, mi.pss, mi.name, true);
17778 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17779 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17781 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17782 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17783 stack.append(DUMP_MEM_OOM_LABEL[k]);
17785 stack.append(DUMP_MEM_OOM_ADJ[k]);
17792 appendMemInfo(fullNativeBuilder, mi);
17793 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17794 // The short form only has native processes that are >= 512K.
17795 if (mi.pss >= 512) {
17796 appendMemInfo(shortNativeBuilder, mi);
17798 extraNativeRam += mi.pss;
17799 extraNativeMemtrack += mi.memtrack;
17802 // Short form has all other details, but if we have collected RAM
17803 // from smaller native processes let's dump a summary of that.
17804 if (extraNativeRam > 0) {
17805 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17806 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17807 shortNativeBuilder.append('\n');
17808 extraNativeRam = 0;
17810 appendMemInfo(fullJavaBuilder, mi);
17814 fullJavaBuilder.append(" ");
17815 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17816 fullJavaBuilder.append(": TOTAL");
17817 if (totalMemtrack > 0) {
17818 fullJavaBuilder.append(" (");
17819 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17820 fullJavaBuilder.append(" memtrack)");
17823 fullJavaBuilder.append("\n");
17825 MemInfoReader memInfo = new MemInfoReader();
17826 memInfo.readMemInfo();
17827 final long[] infos = memInfo.getRawInfo();
17829 StringBuilder memInfoBuilder = new StringBuilder(1024);
17830 Debug.getMemInfo(infos);
17831 memInfoBuilder.append(" MemInfo: ");
17832 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17833 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17834 memInfoBuilder.append(stringifyKBSize(
17835 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17836 memInfoBuilder.append(stringifyKBSize(
17837 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17838 memInfoBuilder.append(stringifyKBSize(
17839 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17840 memInfoBuilder.append(" ");
17841 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17842 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17843 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17844 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17845 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17846 memInfoBuilder.append(" ZRAM: ");
17847 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17848 memInfoBuilder.append(" RAM, ");
17849 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17850 memInfoBuilder.append(" swap total, ");
17851 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17852 memInfoBuilder.append(" swap free\n");
17854 final long[] ksm = getKsmInfo();
17855 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17856 || ksm[KSM_VOLATILE] != 0) {
17857 memInfoBuilder.append(" KSM: ");
17858 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17859 memInfoBuilder.append(" saved from shared ");
17860 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17861 memInfoBuilder.append("\n ");
17862 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17863 memInfoBuilder.append(" unshared; ");
17864 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17865 memInfoBuilder.append(" volatile\n");
17867 memInfoBuilder.append(" Free RAM: ");
17868 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17869 + memInfo.getFreeSizeKb()));
17870 memInfoBuilder.append("\n");
17871 memInfoBuilder.append(" Used RAM: ");
17872 memInfoBuilder.append(stringifyKBSize(
17873 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17874 memInfoBuilder.append("\n");
17875 memInfoBuilder.append(" Lost RAM: ");
17876 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17877 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17878 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17879 memInfoBuilder.append("\n");
17880 Slog.i(TAG, "Low on memory:");
17881 Slog.i(TAG, shortNativeBuilder.toString());
17882 Slog.i(TAG, fullJavaBuilder.toString());
17883 Slog.i(TAG, memInfoBuilder.toString());
17885 StringBuilder dropBuilder = new StringBuilder(1024);
17887 StringWriter oomSw = new StringWriter();
17888 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17889 StringWriter catSw = new StringWriter();
17890 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17891 String[] emptyArgs = new String[] { };
17892 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17894 String oomString = oomSw.toString();
17896 dropBuilder.append("Low on memory:");
17897 dropBuilder.append(stack);
17898 dropBuilder.append('\n');
17899 dropBuilder.append(fullNativeBuilder);
17900 dropBuilder.append(fullJavaBuilder);
17901 dropBuilder.append('\n');
17902 dropBuilder.append(memInfoBuilder);
17903 dropBuilder.append('\n');
17905 dropBuilder.append(oomString);
17906 dropBuilder.append('\n');
17908 StringWriter catSw = new StringWriter();
17909 synchronized (ActivityManagerService.this) {
17910 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17911 String[] emptyArgs = new String[] { };
17913 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17915 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17916 false, null).dumpLocked();
17918 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17921 dropBuilder.append(catSw.toString());
17922 addErrorToDropBox("lowmem", null, "system_server", null,
17923 null, tag.toString(), dropBuilder.toString(), null, null);
17924 //Slog.i(TAG, "Sent to dropbox:");
17925 //Slog.i(TAG, dropBuilder.toString());
17926 synchronized (ActivityManagerService.this) {
17927 long now = SystemClock.uptimeMillis();
17928 if (mLastMemUsageReportTime < now) {
17929 mLastMemUsageReportTime = now;
17935 * Searches array of arguments for the specified string
17936 * @param args array of argument strings
17937 * @param value value to search for
17938 * @return true if the value is contained in the array
17940 private static boolean scanArgs(String[] args, String value) {
17941 if (args != null) {
17942 for (String arg : args) {
17943 if (value.equals(arg)) {
17951 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17952 ContentProviderRecord cpr, boolean always) {
17953 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17955 if (!inLaunching || always) {
17956 synchronized (cpr) {
17957 cpr.launchingApp = null;
17960 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17961 String names[] = cpr.info.authority.split(";");
17962 for (int j = 0; j < names.length; j++) {
17963 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17967 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17968 ContentProviderConnection conn = cpr.connections.get(i);
17969 if (conn.waiting) {
17970 // If this connection is waiting for the provider, then we don't
17971 // need to mess with its process unless we are always removing
17972 // or for some reason the provider is not currently launching.
17973 if (inLaunching && !always) {
17977 ProcessRecord capp = conn.client;
17979 if (conn.stableCount > 0) {
17980 if (!capp.persistent && capp.thread != null
17982 && capp.pid != MY_PID) {
17983 capp.kill("depends on provider "
17984 + cpr.name.flattenToShortString()
17985 + " in dying proc " + (proc != null ? proc.processName : "??")
17986 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17988 } else if (capp.thread != null && conn.provider.provider != null) {
17990 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17991 } catch (RemoteException e) {
17993 // In the protocol here, we don't expect the client to correctly
17994 // clean up this connection, we'll just remove it.
17995 cpr.connections.remove(i);
17996 if (conn.client.conProviders.remove(conn)) {
17997 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18002 if (inLaunching && always) {
18003 mLaunchingProviders.remove(cpr);
18005 return inLaunching;
18009 * Main code for cleaning up a process when it has gone away. This is
18010 * called both as a result of the process dying, or directly when stopping
18011 * a process when running in single process mode.
18013 * @return Returns true if the given process has been restarted, so the
18014 * app that was passed in must remain on the process lists.
18016 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18017 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18019 removeLruProcessLocked(app);
18020 ProcessList.remove(app.pid);
18023 mProcessesToGc.remove(app);
18024 mPendingPssProcesses.remove(app);
18026 // Dismiss any open dialogs.
18027 if (app.crashDialog != null && !app.forceCrashReport) {
18028 app.crashDialog.dismiss();
18029 app.crashDialog = null;
18031 if (app.anrDialog != null) {
18032 app.anrDialog.dismiss();
18033 app.anrDialog = null;
18035 if (app.waitDialog != null) {
18036 app.waitDialog.dismiss();
18037 app.waitDialog = null;
18040 app.crashing = false;
18041 app.notResponding = false;
18043 app.resetPackageList(mProcessStats);
18044 app.unlinkDeathRecipient();
18045 app.makeInactive(mProcessStats);
18046 app.waitingToKill = null;
18047 app.forcingToImportant = null;
18048 updateProcessForegroundLocked(app, false, false);
18049 app.foregroundActivities = false;
18050 app.hasShownUi = false;
18051 app.treatLikeActivity = false;
18052 app.hasAboveClient = false;
18053 app.hasClientActivities = false;
18055 mServices.killServicesLocked(app, allowRestart);
18057 boolean restart = false;
18059 // Remove published content providers.
18060 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18061 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18062 final boolean always = app.bad || !allowRestart;
18063 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18064 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18065 // We left the provider in the launching list, need to
18070 cpr.provider = null;
18073 app.pubProviders.clear();
18075 // Take care of any launching providers waiting for this process.
18076 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18080 // Unregister from connected content providers.
18081 if (!app.conProviders.isEmpty()) {
18082 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18083 ContentProviderConnection conn = app.conProviders.get(i);
18084 conn.provider.connections.remove(conn);
18085 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18086 conn.provider.name);
18088 app.conProviders.clear();
18091 // At this point there may be remaining entries in mLaunchingProviders
18092 // where we were the only one waiting, so they are no longer of use.
18093 // Look for these and clean up if found.
18094 // XXX Commented out for now. Trying to figure out a way to reproduce
18095 // the actual situation to identify what is actually going on.
18097 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18098 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18099 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18100 synchronized (cpr) {
18101 cpr.launchingApp = null;
18108 skipCurrentReceiverLocked(app);
18110 // Unregister any receivers.
18111 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18112 removeReceiverLocked(app.receivers.valueAt(i));
18114 app.receivers.clear();
18116 // If the app is undergoing backup, tell the backup manager about it
18117 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18118 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18119 + mBackupTarget.appInfo + " died during backup");
18120 mHandler.post(new Runnable() {
18124 IBackupManager bm = IBackupManager.Stub.asInterface(
18125 ServiceManager.getService(Context.BACKUP_SERVICE));
18126 bm.agentDisconnected(app.info.packageName);
18127 } catch (RemoteException e) {
18128 // can't happen; backup manager is local
18134 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18135 ProcessChangeItem item = mPendingProcessChanges.get(i);
18136 if (item.pid == app.pid) {
18137 mPendingProcessChanges.remove(i);
18138 mAvailProcessChanges.add(item);
18141 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18142 null).sendToTarget();
18144 // If the caller is restarting this app, then leave it in its
18145 // current lists and let the caller take care of it.
18150 if (!app.persistent || app.isolated) {
18151 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18152 "Removing non-persistent process during cleanup: " + app);
18153 if (!replacingPid) {
18154 removeProcessNameLocked(app.processName, app.uid, app);
18156 if (mHeavyWeightProcess == app) {
18157 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18158 mHeavyWeightProcess.userId, 0));
18159 mHeavyWeightProcess = null;
18161 } else if (!app.removed) {
18162 // This app is persistent, so we need to keep its record around.
18163 // If it is not already on the pending app list, add it there
18164 // and start a new process for it.
18165 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18166 mPersistentStartingProcesses.add(app);
18170 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18171 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18172 mProcessesOnHold.remove(app);
18174 if (app == mHomeProcess) {
18175 mHomeProcess = null;
18177 if (app == mPreviousProcess) {
18178 mPreviousProcess = null;
18181 if (restart && !app.isolated) {
18182 // We have components that still need to be running in the
18183 // process, so re-launch it.
18185 ProcessList.remove(app.pid);
18187 addProcessNameLocked(app);
18188 startProcessLocked(app, "restart", app.processName);
18190 } else if (app.pid > 0 && app.pid != MY_PID) {
18193 synchronized (mPidsSelfLocked) {
18194 mPidsSelfLocked.remove(app.pid);
18195 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18197 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18198 if (app.isolated) {
18199 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18206 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18207 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18208 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18209 if (cpr.launchingApp == app) {
18216 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18217 // Look through the content providers we are waiting to have launched,
18218 // and if any run in this process then either schedule a restart of
18219 // the process or kill the client waiting for it if this process has
18221 boolean restart = false;
18222 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18223 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18224 if (cpr.launchingApp == app) {
18225 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18228 removeDyingProviderLocked(app, cpr, true);
18235 // =========================================================
18237 // =========================================================
18240 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18242 enforceNotIsolatedCaller("getServices");
18244 final int callingUid = Binder.getCallingUid();
18245 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18246 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18247 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18249 synchronized (this) {
18250 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18251 allowed, canInteractAcrossUsers);
18256 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18257 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18258 synchronized (this) {
18259 return mServices.getRunningServiceControlPanelLocked(name);
18264 public ComponentName startService(IApplicationThread caller, Intent service,
18265 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18266 throws TransactionTooLargeException {
18267 enforceNotIsolatedCaller("startService");
18268 // Refuse possible leaked file descriptors
18269 if (service != null && service.hasFileDescriptors() == true) {
18270 throw new IllegalArgumentException("File descriptors passed in Intent");
18273 if (callingPackage == null) {
18274 throw new IllegalArgumentException("callingPackage cannot be null");
18277 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18278 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18279 synchronized(this) {
18280 final int callingPid = Binder.getCallingPid();
18281 final int callingUid = Binder.getCallingUid();
18282 final long origId = Binder.clearCallingIdentity();
18285 res = mServices.startServiceLocked(caller, service,
18286 resolvedType, callingPid, callingUid,
18287 requireForeground, callingPackage, userId);
18289 Binder.restoreCallingIdentity(origId);
18295 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18296 boolean fgRequired, String callingPackage, int userId)
18297 throws TransactionTooLargeException {
18298 synchronized(this) {
18299 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18300 "startServiceInPackage: " + service + " type=" + resolvedType);
18301 final long origId = Binder.clearCallingIdentity();
18304 res = mServices.startServiceLocked(null, service,
18305 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18307 Binder.restoreCallingIdentity(origId);
18314 public int stopService(IApplicationThread caller, Intent service,
18315 String resolvedType, int userId) {
18316 enforceNotIsolatedCaller("stopService");
18317 // Refuse possible leaked file descriptors
18318 if (service != null && service.hasFileDescriptors() == true) {
18319 throw new IllegalArgumentException("File descriptors passed in Intent");
18322 synchronized(this) {
18323 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18328 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18329 enforceNotIsolatedCaller("peekService");
18330 // Refuse possible leaked file descriptors
18331 if (service != null && service.hasFileDescriptors() == true) {
18332 throw new IllegalArgumentException("File descriptors passed in Intent");
18335 if (callingPackage == null) {
18336 throw new IllegalArgumentException("callingPackage cannot be null");
18339 synchronized(this) {
18340 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18345 public boolean stopServiceToken(ComponentName className, IBinder token,
18347 synchronized(this) {
18348 return mServices.stopServiceTokenLocked(className, token, startId);
18353 public void setServiceForeground(ComponentName className, IBinder token,
18354 int id, Notification notification, int flags) {
18355 synchronized(this) {
18356 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18361 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18362 boolean requireFull, String name, String callerPackage) {
18363 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18364 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18367 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18368 String className, int flags) {
18369 boolean result = false;
18370 // For apps that don't have pre-defined UIDs, check for permission
18371 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18372 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18373 if (ActivityManager.checkUidPermission(
18374 INTERACT_ACROSS_USERS,
18375 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18376 ComponentName comp = new ComponentName(aInfo.packageName, className);
18377 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18378 + " requests FLAG_SINGLE_USER, but app does not hold "
18379 + INTERACT_ACROSS_USERS;
18381 throw new SecurityException(msg);
18383 // Permission passed
18386 } else if ("system".equals(componentProcessName)) {
18388 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18389 // Phone app and persistent apps are allowed to export singleuser providers.
18390 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18391 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18393 if (DEBUG_MU) Slog.v(TAG_MU,
18394 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18395 + Integer.toHexString(flags) + ") = " + result);
18400 * Checks to see if the caller is in the same app as the singleton
18401 * component, or the component is in a special app. It allows special apps
18402 * to export singleton components but prevents exporting singleton
18403 * components for regular apps.
18405 boolean isValidSingletonCall(int callingUid, int componentUid) {
18406 int componentAppId = UserHandle.getAppId(componentUid);
18407 return UserHandle.isSameApp(callingUid, componentUid)
18408 || componentAppId == SYSTEM_UID
18409 || componentAppId == PHONE_UID
18410 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18411 == PackageManager.PERMISSION_GRANTED;
18414 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18415 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18416 int userId) throws TransactionTooLargeException {
18417 enforceNotIsolatedCaller("bindService");
18419 // Refuse possible leaked file descriptors
18420 if (service != null && service.hasFileDescriptors() == true) {
18421 throw new IllegalArgumentException("File descriptors passed in Intent");
18424 if (callingPackage == null) {
18425 throw new IllegalArgumentException("callingPackage cannot be null");
18428 synchronized(this) {
18429 return mServices.bindServiceLocked(caller, token, service,
18430 resolvedType, connection, flags, callingPackage, userId);
18434 public boolean unbindService(IServiceConnection connection) {
18435 synchronized (this) {
18436 return mServices.unbindServiceLocked(connection);
18440 public void publishService(IBinder token, Intent intent, IBinder service) {
18441 // Refuse possible leaked file descriptors
18442 if (intent != null && intent.hasFileDescriptors() == true) {
18443 throw new IllegalArgumentException("File descriptors passed in Intent");
18446 synchronized(this) {
18447 if (!(token instanceof ServiceRecord)) {
18448 throw new IllegalArgumentException("Invalid service token");
18450 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18454 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18455 // Refuse possible leaked file descriptors
18456 if (intent != null && intent.hasFileDescriptors() == true) {
18457 throw new IllegalArgumentException("File descriptors passed in Intent");
18460 synchronized(this) {
18461 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18465 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18466 synchronized(this) {
18467 if (!(token instanceof ServiceRecord)) {
18468 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18469 throw new IllegalArgumentException("Invalid service token");
18471 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18475 // =========================================================
18476 // BACKUP AND RESTORE
18477 // =========================================================
18479 // Cause the target app to be launched if necessary and its backup agent
18480 // instantiated. The backup agent will invoke backupAgentCreated() on the
18481 // activity manager to announce its creation.
18482 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18483 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18484 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18486 IPackageManager pm = AppGlobals.getPackageManager();
18487 ApplicationInfo app = null;
18489 app = pm.getApplicationInfo(packageName, 0, userId);
18490 } catch (RemoteException e) {
18491 // can't happen; package manager is process-local
18494 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18501 synchronized(this) {
18502 // !!! TODO: currently no check here that we're already bound
18503 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18504 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18505 synchronized (stats) {
18506 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18509 // Backup agent is now in use, its package can't be stopped.
18511 AppGlobals.getPackageManager().setPackageStoppedState(
18512 app.packageName, false, UserHandle.getUserId(app.uid));
18513 } catch (RemoteException e) {
18514 } catch (IllegalArgumentException e) {
18515 Slog.w(TAG, "Failed trying to unstop package "
18516 + app.packageName + ": " + e);
18519 BackupRecord r = new BackupRecord(ss, app, backupMode);
18520 ComponentName hostingName =
18521 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18522 ? new ComponentName(app.packageName, app.backupAgentName)
18523 : new ComponentName("android", "FullBackupAgent");
18524 // startProcessLocked() returns existing proc's record if it's already running
18525 ProcessRecord proc = startProcessLocked(app.processName, app,
18526 false, 0, "backup", hostingName, false, false, false);
18527 if (proc == null) {
18528 Slog.e(TAG, "Unable to start backup agent process " + r);
18532 // If the app is a regular app (uid >= 10000) and not the system server or phone
18533 // process, etc, then mark it as being in full backup so that certain calls to the
18534 // process can be blocked. This is not reset to false anywhere because we kill the
18535 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18536 if (UserHandle.isApp(app.uid) &&
18537 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18538 proc.inFullBackup = true;
18541 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18542 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18544 mBackupAppName = app.packageName;
18546 // Try not to kill the process during backup
18547 updateOomAdjLocked(proc, true);
18549 // If the process is already attached, schedule the creation of the backup agent now.
18550 // If it is not yet live, this will be done when it attaches to the framework.
18551 if (proc.thread != null) {
18552 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18554 proc.thread.scheduleCreateBackupAgent(app,
18555 compatibilityInfoForPackageLocked(app), backupMode);
18556 } catch (RemoteException e) {
18557 // Will time out on the backup manager side
18560 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18562 // Invariants: at this point, the target app process exists and the application
18563 // is either already running or in the process of coming up. mBackupTarget and
18564 // mBackupAppName describe the app, so that when it binds back to the AM we
18565 // know that it's scheduled for a backup-agent operation.
18568 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18569 if (oldBackupUid != -1) {
18570 js.removeBackingUpUid(oldBackupUid);
18572 if (newBackupUid != -1) {
18573 js.addBackingUpUid(newBackupUid);
18580 public void clearPendingBackup() {
18581 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18582 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18584 synchronized (this) {
18585 mBackupTarget = null;
18586 mBackupAppName = null;
18589 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18590 js.clearAllBackingUpUids();
18593 // A backup agent has just come up
18594 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18595 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18598 synchronized(this) {
18599 if (!agentPackageName.equals(mBackupAppName)) {
18600 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18605 long oldIdent = Binder.clearCallingIdentity();
18607 IBackupManager bm = IBackupManager.Stub.asInterface(
18608 ServiceManager.getService(Context.BACKUP_SERVICE));
18609 bm.agentConnected(agentPackageName, agent);
18610 } catch (RemoteException e) {
18611 // can't happen; the backup manager service is local
18612 } catch (Exception e) {
18613 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18614 e.printStackTrace();
18616 Binder.restoreCallingIdentity(oldIdent);
18620 // done with this agent
18621 public void unbindBackupAgent(ApplicationInfo appInfo) {
18622 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18623 if (appInfo == null) {
18624 Slog.w(TAG, "unbind backup agent for null app");
18630 synchronized(this) {
18632 if (mBackupAppName == null) {
18633 Slog.w(TAG, "Unbinding backup agent with no active backup");
18637 if (!mBackupAppName.equals(appInfo.packageName)) {
18638 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18642 // Not backing this app up any more; reset its OOM adjustment
18643 final ProcessRecord proc = mBackupTarget.app;
18644 updateOomAdjLocked(proc, true);
18645 proc.inFullBackup = false;
18647 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18649 // If the app crashed during backup, 'thread' will be null here
18650 if (proc.thread != null) {
18652 proc.thread.scheduleDestroyBackupAgent(appInfo,
18653 compatibilityInfoForPackageLocked(appInfo));
18654 } catch (Exception e) {
18655 Slog.e(TAG, "Exception when unbinding backup agent:");
18656 e.printStackTrace();
18660 mBackupTarget = null;
18661 mBackupAppName = null;
18665 if (oldBackupUid != -1) {
18666 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18667 js.removeBackingUpUid(oldBackupUid);
18671 // =========================================================
18673 // =========================================================
18675 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18676 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18679 // Easy case -- we have the app's ProcessRecord.
18680 if (record != null) {
18681 return record.info.isInstantApp();
18683 // Otherwise check with PackageManager.
18684 if (callerPackage == null) {
18685 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18686 throw new IllegalArgumentException("Calling application did not provide package name");
18688 mAppOpsService.checkPackage(uid, callerPackage);
18690 IPackageManager pm = AppGlobals.getPackageManager();
18691 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18692 } catch (RemoteException e) {
18693 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18698 boolean isPendingBroadcastProcessLocked(int pid) {
18699 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18700 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18703 void skipPendingBroadcastLocked(int pid) {
18704 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18705 for (BroadcastQueue queue : mBroadcastQueues) {
18706 queue.skipPendingBroadcastLocked(pid);
18710 // The app just attached; send any pending broadcasts that it should receive
18711 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18712 boolean didSomething = false;
18713 for (BroadcastQueue queue : mBroadcastQueues) {
18714 didSomething |= queue.sendPendingBroadcastsLocked(app);
18716 return didSomething;
18719 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18720 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18722 enforceNotIsolatedCaller("registerReceiver");
18723 ArrayList<Intent> stickyIntents = null;
18724 ProcessRecord callerApp = null;
18725 final boolean visibleToInstantApps
18726 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18729 boolean instantApp;
18730 synchronized(this) {
18731 if (caller != null) {
18732 callerApp = getRecordForAppLocked(caller);
18733 if (callerApp == null) {
18734 throw new SecurityException(
18735 "Unable to find app for caller " + caller
18736 + " (pid=" + Binder.getCallingPid()
18737 + ") when registering receiver " + receiver);
18739 if (callerApp.info.uid != SYSTEM_UID &&
18740 !callerApp.pkgList.containsKey(callerPackage) &&
18741 !"android".equals(callerPackage)) {
18742 throw new SecurityException("Given caller package " + callerPackage
18743 + " is not running in process " + callerApp);
18745 callingUid = callerApp.info.uid;
18746 callingPid = callerApp.pid;
18748 callerPackage = null;
18749 callingUid = Binder.getCallingUid();
18750 callingPid = Binder.getCallingPid();
18753 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18754 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18755 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18757 Iterator<String> actions = filter.actionsIterator();
18758 if (actions == null) {
18759 ArrayList<String> noAction = new ArrayList<String>(1);
18760 noAction.add(null);
18761 actions = noAction.iterator();
18764 // Collect stickies of users
18765 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18766 while (actions.hasNext()) {
18767 String action = actions.next();
18768 for (int id : userIds) {
18769 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18770 if (stickies != null) {
18771 ArrayList<Intent> intents = stickies.get(action);
18772 if (intents != null) {
18773 if (stickyIntents == null) {
18774 stickyIntents = new ArrayList<Intent>();
18776 stickyIntents.addAll(intents);
18783 ArrayList<Intent> allSticky = null;
18784 if (stickyIntents != null) {
18785 final ContentResolver resolver = mContext.getContentResolver();
18786 // Look for any matching sticky broadcasts...
18787 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18788 Intent intent = stickyIntents.get(i);
18789 // Don't provided intents that aren't available to instant apps.
18791 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18794 // If intent has scheme "content", it will need to acccess
18795 // provider that needs to lock mProviderMap in ActivityThread
18796 // and also it may need to wait application response, so we
18797 // cannot lock ActivityManagerService here.
18798 if (filter.match(resolver, intent, true, TAG) >= 0) {
18799 if (allSticky == null) {
18800 allSticky = new ArrayList<Intent>();
18802 allSticky.add(intent);
18807 // The first sticky in the list is returned directly back to the client.
18808 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18809 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18810 if (receiver == null) {
18814 synchronized (this) {
18815 if (callerApp != null && (callerApp.thread == null
18816 || callerApp.thread.asBinder() != caller.asBinder())) {
18817 // Original caller already died
18820 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18822 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18824 if (rl.app != null) {
18825 rl.app.receivers.add(rl);
18828 receiver.asBinder().linkToDeath(rl, 0);
18829 } catch (RemoteException e) {
18832 rl.linkedToDeath = true;
18834 mRegisteredReceivers.put(receiver.asBinder(), rl);
18835 } else if (rl.uid != callingUid) {
18836 throw new IllegalArgumentException(
18837 "Receiver requested to register for uid " + callingUid
18838 + " was previously registered for uid " + rl.uid
18839 + " callerPackage is " + callerPackage);
18840 } else if (rl.pid != callingPid) {
18841 throw new IllegalArgumentException(
18842 "Receiver requested to register for pid " + callingPid
18843 + " was previously registered for pid " + rl.pid
18844 + " callerPackage is " + callerPackage);
18845 } else if (rl.userId != userId) {
18846 throw new IllegalArgumentException(
18847 "Receiver requested to register for user " + userId
18848 + " was previously registered for user " + rl.userId
18849 + " callerPackage is " + callerPackage);
18851 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18852 permission, callingUid, userId, instantApp, visibleToInstantApps);
18854 if (!bf.debugCheck()) {
18855 Slog.w(TAG, "==> For Dynamic broadcast");
18857 mReceiverResolver.addFilter(bf);
18859 // Enqueue broadcasts for all existing stickies that match
18861 if (allSticky != null) {
18862 ArrayList receivers = new ArrayList();
18865 final int stickyCount = allSticky.size();
18866 for (int i = 0; i < stickyCount; i++) {
18867 Intent intent = allSticky.get(i);
18868 BroadcastQueue queue = broadcastQueueForIntent(intent);
18869 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18870 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18871 null, 0, null, null, false, true, true, -1);
18872 queue.enqueueParallelBroadcastLocked(r);
18873 queue.scheduleBroadcastsLocked();
18881 public void unregisterReceiver(IIntentReceiver receiver) {
18882 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18884 final long origId = Binder.clearCallingIdentity();
18886 boolean doTrim = false;
18888 synchronized(this) {
18889 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18891 final BroadcastRecord r = rl.curBroadcast;
18892 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18893 final boolean doNext = r.queue.finishReceiverLocked(
18894 r, r.resultCode, r.resultData, r.resultExtras,
18895 r.resultAbort, false);
18898 r.queue.processNextBroadcast(false);
18902 if (rl.app != null) {
18903 rl.app.receivers.remove(rl);
18905 removeReceiverLocked(rl);
18906 if (rl.linkedToDeath) {
18907 rl.linkedToDeath = false;
18908 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18913 // If we actually concluded any broadcasts, we might now be able
18914 // to trim the recipients' apps from our working set
18916 trimApplications();
18921 Binder.restoreCallingIdentity(origId);
18925 void removeReceiverLocked(ReceiverList rl) {
18926 mRegisteredReceivers.remove(rl.receiver.asBinder());
18927 for (int i = rl.size() - 1; i >= 0; i--) {
18928 mReceiverResolver.removeFilter(rl.get(i));
18932 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18933 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18934 ProcessRecord r = mLruProcesses.get(i);
18935 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18937 r.thread.dispatchPackageBroadcast(cmd, packages);
18938 } catch (RemoteException ex) {
18944 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18945 int callingUid, int[] users) {
18946 // TODO: come back and remove this assumption to triage all broadcasts
18947 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18949 List<ResolveInfo> receivers = null;
18951 HashSet<ComponentName> singleUserReceivers = null;
18952 boolean scannedFirstReceivers = false;
18953 for (int user : users) {
18954 // Skip users that have Shell restrictions, with exception of always permitted
18955 // Shell broadcasts
18956 if (callingUid == SHELL_UID
18957 && mUserController.hasUserRestriction(
18958 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18959 && !isPermittedShellBroadcast(intent)) {
18962 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18963 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18964 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18965 // If this is not the system user, we need to check for
18966 // any receivers that should be filtered out.
18967 for (int i=0; i<newReceivers.size(); i++) {
18968 ResolveInfo ri = newReceivers.get(i);
18969 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18970 newReceivers.remove(i);
18975 if (newReceivers != null && newReceivers.size() == 0) {
18976 newReceivers = null;
18978 if (receivers == null) {
18979 receivers = newReceivers;
18980 } else if (newReceivers != null) {
18981 // We need to concatenate the additional receivers
18982 // found with what we have do far. This would be easy,
18983 // but we also need to de-dup any receivers that are
18985 if (!scannedFirstReceivers) {
18986 // Collect any single user receivers we had already retrieved.
18987 scannedFirstReceivers = true;
18988 for (int i=0; i<receivers.size(); i++) {
18989 ResolveInfo ri = receivers.get(i);
18990 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18991 ComponentName cn = new ComponentName(
18992 ri.activityInfo.packageName, ri.activityInfo.name);
18993 if (singleUserReceivers == null) {
18994 singleUserReceivers = new HashSet<ComponentName>();
18996 singleUserReceivers.add(cn);
19000 // Add the new results to the existing results, tracking
19001 // and de-dupping single user receivers.
19002 for (int i=0; i<newReceivers.size(); i++) {
19003 ResolveInfo ri = newReceivers.get(i);
19004 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19005 ComponentName cn = new ComponentName(
19006 ri.activityInfo.packageName, ri.activityInfo.name);
19007 if (singleUserReceivers == null) {
19008 singleUserReceivers = new HashSet<ComponentName>();
19010 if (!singleUserReceivers.contains(cn)) {
19011 singleUserReceivers.add(cn);
19020 } catch (RemoteException ex) {
19021 // pm is in same process, this will never happen.
19026 private boolean isPermittedShellBroadcast(Intent intent) {
19027 // remote bugreport should always be allowed to be taken
19028 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19031 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19032 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19033 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19034 // Don't yell about broadcasts sent via shell
19038 final String action = intent.getAction();
19039 if (isProtectedBroadcast
19040 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19041 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19042 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19043 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19044 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19045 || Intent.ACTION_MASTER_CLEAR.equals(action)
19046 || Intent.ACTION_FACTORY_RESET.equals(action)
19047 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19048 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19049 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19050 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19051 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19052 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19053 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19054 // Broadcast is either protected, or it's a public action that
19055 // we've relaxed, so it's fine for system internals to send.
19059 // This broadcast may be a problem... but there are often system components that
19060 // want to send an internal broadcast to themselves, which is annoying to have to
19061 // explicitly list each action as a protected broadcast, so we will check for that
19062 // one safe case and allow it: an explicit broadcast, only being received by something
19063 // that has protected itself.
19064 if (receivers != null && receivers.size() > 0
19065 && (intent.getPackage() != null || intent.getComponent() != null)) {
19066 boolean allProtected = true;
19067 for (int i = receivers.size()-1; i >= 0; i--) {
19068 Object target = receivers.get(i);
19069 if (target instanceof ResolveInfo) {
19070 ResolveInfo ri = (ResolveInfo)target;
19071 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19072 allProtected = false;
19076 BroadcastFilter bf = (BroadcastFilter)target;
19077 if (bf.requiredPermission == null) {
19078 allProtected = false;
19083 if (allProtected) {
19089 // The vast majority of broadcasts sent from system internals
19090 // should be protected to avoid security holes, so yell loudly
19091 // to ensure we examine these cases.
19092 if (callerApp != null) {
19093 Log.wtf(TAG, "Sending non-protected broadcast " + action
19094 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19097 Log.wtf(TAG, "Sending non-protected broadcast " + action
19098 + " from system uid " + UserHandle.formatUid(callingUid)
19099 + " pkg " + callerPackage,
19104 final int broadcastIntentLocked(ProcessRecord callerApp,
19105 String callerPackage, Intent intent, String resolvedType,
19106 IIntentReceiver resultTo, int resultCode, String resultData,
19107 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19108 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19109 intent = new Intent(intent);
19111 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19112 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19113 if (callerInstantApp) {
19114 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19117 // By default broadcasts do not go to stopped apps.
19118 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19120 // If we have not finished booting, don't allow this to launch new processes.
19121 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19122 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19125 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19126 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19127 + " ordered=" + ordered + " userid=" + userId);
19128 if ((resultTo != null) && !ordered) {
19129 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19132 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19133 ALLOW_NON_FULL, "broadcast", callerPackage);
19135 // Make sure that the user who is receiving this broadcast is running.
19136 // If not, we will just skip it. Make an exception for shutdown broadcasts
19137 // and upgrade steps.
19139 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19140 if ((callingUid != SYSTEM_UID
19141 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19142 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19143 Slog.w(TAG, "Skipping broadcast of " + intent
19144 + ": user " + userId + " is stopped");
19145 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19149 BroadcastOptions brOptions = null;
19150 if (bOptions != null) {
19151 brOptions = new BroadcastOptions(bOptions);
19152 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19153 // See if the caller is allowed to do this. Note we are checking against
19154 // the actual real caller (not whoever provided the operation as say a
19155 // PendingIntent), because that who is actually supplied the arguments.
19156 if (checkComponentPermission(
19157 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19158 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19159 != PackageManager.PERMISSION_GRANTED) {
19160 String msg = "Permission Denial: " + intent.getAction()
19161 + " broadcast from " + callerPackage + " (pid=" + callingPid
19162 + ", uid=" + callingUid + ")"
19164 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19166 throw new SecurityException(msg);
19171 // Verify that protected broadcasts are only being sent by system code,
19172 // and that system code is only sending protected broadcasts.
19173 final String action = intent.getAction();
19174 final boolean isProtectedBroadcast;
19176 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19177 } catch (RemoteException e) {
19178 Slog.w(TAG, "Remote exception", e);
19179 return ActivityManager.BROADCAST_SUCCESS;
19182 final boolean isCallerSystem;
19183 switch (UserHandle.getAppId(callingUid)) {
19187 case BLUETOOTH_UID:
19189 isCallerSystem = true;
19192 isCallerSystem = (callerApp != null) && callerApp.persistent;
19196 // First line security check before anything else: stop non-system apps from
19197 // sending protected broadcasts.
19198 if (!isCallerSystem) {
19199 if (isProtectedBroadcast) {
19200 String msg = "Permission Denial: not allowed to send broadcast "
19201 + action + " from pid="
19202 + callingPid + ", uid=" + callingUid;
19204 throw new SecurityException(msg);
19206 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19207 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19208 // Special case for compatibility: we don't want apps to send this,
19209 // but historically it has not been protected and apps may be using it
19210 // to poke their own app widget. So, instead of making it protected,
19211 // just limit it to the caller.
19212 if (callerPackage == null) {
19213 String msg = "Permission Denial: not allowed to send broadcast "
19214 + action + " from unknown caller.";
19216 throw new SecurityException(msg);
19217 } else if (intent.getComponent() != null) {
19218 // They are good enough to send to an explicit component... verify
19219 // it is being sent to the calling app.
19220 if (!intent.getComponent().getPackageName().equals(
19222 String msg = "Permission Denial: not allowed to send broadcast "
19224 + intent.getComponent().getPackageName() + " from "
19227 throw new SecurityException(msg);
19230 // Limit broadcast to their own package.
19231 intent.setPackage(callerPackage);
19236 if (action != null) {
19237 if (getBackgroundLaunchBroadcasts().contains(action)) {
19238 if (DEBUG_BACKGROUND_CHECK) {
19239 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19241 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19245 case Intent.ACTION_UID_REMOVED:
19246 case Intent.ACTION_PACKAGE_REMOVED:
19247 case Intent.ACTION_PACKAGE_CHANGED:
19248 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19249 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19250 case Intent.ACTION_PACKAGES_SUSPENDED:
19251 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19252 // Handle special intents: if this broadcast is from the package
19253 // manager about a package being removed, we need to remove all of
19254 // its activities from the history stack.
19255 if (checkComponentPermission(
19256 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19257 callingPid, callingUid, -1, true)
19258 != PackageManager.PERMISSION_GRANTED) {
19259 String msg = "Permission Denial: " + intent.getAction()
19260 + " broadcast from " + callerPackage + " (pid=" + callingPid
19261 + ", uid=" + callingUid + ")"
19263 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19265 throw new SecurityException(msg);
19268 case Intent.ACTION_UID_REMOVED:
19269 final int uid = getUidFromIntent(intent);
19271 mBatteryStatsService.removeUid(uid);
19272 mAppOpsService.uidRemoved(uid);
19275 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19276 // If resources are unavailable just force stop all those packages
19277 // and flush the attribute cache as well.
19279 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19280 if (list != null && list.length > 0) {
19281 for (int i = 0; i < list.length; i++) {
19282 forceStopPackageLocked(list[i], -1, false, true, true,
19283 false, false, userId, "storage unmount");
19285 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19286 sendPackageBroadcastLocked(
19287 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19291 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19292 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19294 case Intent.ACTION_PACKAGE_REMOVED:
19295 case Intent.ACTION_PACKAGE_CHANGED:
19296 Uri data = intent.getData();
19298 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19299 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19300 final boolean replacing =
19301 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19302 final boolean killProcess =
19303 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19304 final boolean fullUninstall = removed && !replacing;
19307 forceStopPackageLocked(ssp, UserHandle.getAppId(
19308 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19309 false, true, true, false, fullUninstall, userId,
19310 removed ? "pkg removed" : "pkg changed");
19312 final int cmd = killProcess
19313 ? ApplicationThreadConstants.PACKAGE_REMOVED
19314 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19315 sendPackageBroadcastLocked(cmd,
19316 new String[] {ssp}, userId);
19317 if (fullUninstall) {
19318 mAppOpsService.packageRemoved(
19319 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19321 // Remove all permissions granted from/to this package
19322 removeUriPermissionsForPackageLocked(ssp, userId, true);
19324 removeTasksByPackageNameLocked(ssp, userId);
19326 mServices.forceStopPackageLocked(ssp, userId);
19328 // Hide the "unsupported display" dialog if necessary.
19329 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19330 mUnsupportedDisplaySizeDialog.getPackageName())) {
19331 mUnsupportedDisplaySizeDialog.dismiss();
19332 mUnsupportedDisplaySizeDialog = null;
19334 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19335 mBatteryStatsService.notePackageUninstalled(ssp);
19339 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19340 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19341 userId, ProcessList.INVALID_ADJ,
19342 false, true, true, false, "change " + ssp);
19344 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19345 intent.getStringArrayExtra(
19346 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19350 case Intent.ACTION_PACKAGES_SUSPENDED:
19351 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19352 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19353 intent.getAction());
19354 final String[] packageNames = intent.getStringArrayExtra(
19355 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19356 final int userHandle = intent.getIntExtra(
19357 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19359 synchronized(ActivityManagerService.this) {
19360 mRecentTasks.onPackagesSuspendedChanged(
19361 packageNames, suspended, userHandle);
19366 case Intent.ACTION_PACKAGE_REPLACED:
19368 final Uri data = intent.getData();
19370 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19371 ApplicationInfo aInfo = null;
19373 aInfo = AppGlobals.getPackageManager()
19374 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19375 } catch (RemoteException ignore) {}
19376 if (aInfo == null) {
19377 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19378 + " ssp=" + ssp + " data=" + data);
19379 return ActivityManager.BROADCAST_SUCCESS;
19381 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19382 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19383 new String[] {ssp}, userId);
19387 case Intent.ACTION_PACKAGE_ADDED:
19389 // Special case for adding a package: by default turn on compatibility mode.
19390 Uri data = intent.getData();
19392 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19393 final boolean replacing =
19394 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19395 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19398 ApplicationInfo ai = AppGlobals.getPackageManager().
19399 getApplicationInfo(ssp, 0, 0);
19400 mBatteryStatsService.notePackageInstalled(ssp,
19401 ai != null ? ai.versionCode : 0);
19402 } catch (RemoteException e) {
19407 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19409 Uri data = intent.getData();
19411 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19412 // Hide the "unsupported display" dialog if necessary.
19413 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19414 mUnsupportedDisplaySizeDialog.getPackageName())) {
19415 mUnsupportedDisplaySizeDialog.dismiss();
19416 mUnsupportedDisplaySizeDialog = null;
19418 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19422 case Intent.ACTION_TIMEZONE_CHANGED:
19423 // If this is the time zone changed action, queue up a message that will reset
19424 // the timezone of all currently running processes. This message will get
19425 // queued up before the broadcast happens.
19426 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19428 case Intent.ACTION_TIME_CHANGED:
19429 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19430 // the tri-state value it may contain and "unknown".
19431 // For convenience we re-use the Intent extra values.
19432 final int NO_EXTRA_VALUE_FOUND = -1;
19433 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19434 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19435 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19436 // Only send a message if the time preference is available.
19437 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19438 Message updateTimePreferenceMsg =
19439 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19440 timeFormatPreferenceMsgValue, 0);
19441 mHandler.sendMessage(updateTimePreferenceMsg);
19443 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19444 synchronized (stats) {
19445 stats.noteCurrentTimeChangedLocked();
19448 case Intent.ACTION_CLEAR_DNS_CACHE:
19449 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19451 case Proxy.PROXY_CHANGE_ACTION:
19452 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19453 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19455 case android.hardware.Camera.ACTION_NEW_PICTURE:
19456 case android.hardware.Camera.ACTION_NEW_VIDEO:
19457 // In N we just turned these off; in O we are turing them back on partly,
19458 // only for registered receivers. This will still address the main problem
19459 // (a spam of apps waking up when a picture is taken putting significant
19460 // memory pressure on the system at a bad point), while still allowing apps
19461 // that are already actively running to know about this happening.
19462 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19464 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19465 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19467 case "com.android.launcher.action.INSTALL_SHORTCUT":
19468 // As of O, we no longer support this broadcasts, even for pre-O apps.
19469 // Apps should now be using ShortcutManager.pinRequestShortcut().
19470 Log.w(TAG, "Broadcast " + action
19471 + " no longer supported. It will not be delivered.");
19472 return ActivityManager.BROADCAST_SUCCESS;
19475 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19476 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19477 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19478 final int uid = getUidFromIntent(intent);
19480 final UidRecord uidRec = mActiveUids.get(uid);
19481 if (uidRec != null) {
19482 uidRec.updateHasInternetPermission();
19488 // Add to the sticky list if requested.
19490 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19491 callingPid, callingUid)
19492 != PackageManager.PERMISSION_GRANTED) {
19493 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19494 + callingPid + ", uid=" + callingUid
19495 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19497 throw new SecurityException(msg);
19499 if (requiredPermissions != null && requiredPermissions.length > 0) {
19500 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19501 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19502 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19504 if (intent.getComponent() != null) {
19505 throw new SecurityException(
19506 "Sticky broadcasts can't target a specific component");
19508 // We use userId directly here, since the "all" target is maintained
19509 // as a separate set of sticky broadcasts.
19510 if (userId != UserHandle.USER_ALL) {
19511 // But first, if this is not a broadcast to all users, then
19512 // make sure it doesn't conflict with an existing broadcast to
19514 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19515 UserHandle.USER_ALL);
19516 if (stickies != null) {
19517 ArrayList<Intent> list = stickies.get(intent.getAction());
19518 if (list != null) {
19519 int N = list.size();
19521 for (i=0; i<N; i++) {
19522 if (intent.filterEquals(list.get(i))) {
19523 throw new IllegalArgumentException(
19524 "Sticky broadcast " + intent + " for user "
19525 + userId + " conflicts with existing global broadcast");
19531 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19532 if (stickies == null) {
19533 stickies = new ArrayMap<>();
19534 mStickyBroadcasts.put(userId, stickies);
19536 ArrayList<Intent> list = stickies.get(intent.getAction());
19537 if (list == null) {
19538 list = new ArrayList<>();
19539 stickies.put(intent.getAction(), list);
19541 final int stickiesCount = list.size();
19543 for (i = 0; i < stickiesCount; i++) {
19544 if (intent.filterEquals(list.get(i))) {
19545 // This sticky already exists, replace it.
19546 list.set(i, new Intent(intent));
19550 if (i >= stickiesCount) {
19551 list.add(new Intent(intent));
19556 if (userId == UserHandle.USER_ALL) {
19557 // Caller wants broadcast to go to all started users.
19558 users = mUserController.getStartedUserArrayLocked();
19560 // Caller wants broadcast to go to one specific user.
19561 users = new int[] {userId};
19564 // Figure out who all will receive this broadcast.
19565 List receivers = null;
19566 List<BroadcastFilter> registeredReceivers = null;
19567 // Need to resolve the intent to interested receivers...
19568 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19570 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19572 if (intent.getComponent() == null) {
19573 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19574 // Query one target user at a time, excluding shell-restricted users
19575 for (int i = 0; i < users.length; i++) {
19576 if (mUserController.hasUserRestriction(
19577 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19580 List<BroadcastFilter> registeredReceiversForUser =
19581 mReceiverResolver.queryIntent(intent,
19582 resolvedType, false /*defaultOnly*/, users[i]);
19583 if (registeredReceivers == null) {
19584 registeredReceivers = registeredReceiversForUser;
19585 } else if (registeredReceiversForUser != null) {
19586 registeredReceivers.addAll(registeredReceiversForUser);
19590 registeredReceivers = mReceiverResolver.queryIntent(intent,
19591 resolvedType, false /*defaultOnly*/, userId);
19595 final boolean replacePending =
19596 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19598 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19599 + " replacePending=" + replacePending);
19601 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19602 if (!ordered && NR > 0) {
19603 // If we are not serializing this broadcast, then send the
19604 // registered receivers separately so they don't wait for the
19605 // components to be launched.
19606 if (isCallerSystem) {
19607 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19608 isProtectedBroadcast, registeredReceivers);
19610 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19611 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19612 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19613 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19614 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19615 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19616 final boolean replaced = replacePending
19617 && (queue.replaceParallelBroadcastLocked(r) != null);
19618 // Note: We assume resultTo is null for non-ordered broadcasts.
19620 queue.enqueueParallelBroadcastLocked(r);
19621 queue.scheduleBroadcastsLocked();
19623 registeredReceivers = null;
19627 // Merge into one list.
19629 if (receivers != null) {
19630 // A special case for PACKAGE_ADDED: do not allow the package
19631 // being added to see this broadcast. This prevents them from
19632 // using this as a back door to get run as soon as they are
19633 // installed. Maybe in the future we want to have a special install
19634 // broadcast or such for apps, but we'd like to deliberately make
19636 String skipPackages[] = null;
19637 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19638 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19639 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19640 Uri data = intent.getData();
19641 if (data != null) {
19642 String pkgName = data.getSchemeSpecificPart();
19643 if (pkgName != null) {
19644 skipPackages = new String[] { pkgName };
19647 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19648 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19650 if (skipPackages != null && (skipPackages.length > 0)) {
19651 for (String skipPackage : skipPackages) {
19652 if (skipPackage != null) {
19653 int NT = receivers.size();
19654 for (int it=0; it<NT; it++) {
19655 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19656 if (curt.activityInfo.packageName.equals(skipPackage)) {
19657 receivers.remove(it);
19666 int NT = receivers != null ? receivers.size() : 0;
19668 ResolveInfo curt = null;
19669 BroadcastFilter curr = null;
19670 while (it < NT && ir < NR) {
19671 if (curt == null) {
19672 curt = (ResolveInfo)receivers.get(it);
19674 if (curr == null) {
19675 curr = registeredReceivers.get(ir);
19677 if (curr.getPriority() >= curt.priority) {
19678 // Insert this broadcast record into the final list.
19679 receivers.add(it, curr);
19685 // Skip to the next ResolveInfo in the final list.
19692 if (receivers == null) {
19693 receivers = new ArrayList();
19695 receivers.add(registeredReceivers.get(ir));
19699 if (isCallerSystem) {
19700 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19701 isProtectedBroadcast, receivers);
19704 if ((receivers != null && receivers.size() > 0)
19705 || resultTo != null) {
19706 BroadcastQueue queue = broadcastQueueForIntent(intent);
19707 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19708 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19709 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19710 resultData, resultExtras, ordered, sticky, false, userId);
19712 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19713 + ": prev had " + queue.mOrderedBroadcasts.size());
19714 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19715 "Enqueueing broadcast " + r.intent.getAction());
19717 final BroadcastRecord oldRecord =
19718 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19719 if (oldRecord != null) {
19720 // Replaced, fire the result-to receiver.
19721 if (oldRecord.resultTo != null) {
19722 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19724 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19726 Activity.RESULT_CANCELED, null, null,
19727 false, false, oldRecord.userId);
19728 } catch (RemoteException e) {
19729 Slog.w(TAG, "Failure ["
19730 + queue.mQueueName + "] sending broadcast result of "
19736 queue.enqueueOrderedBroadcastLocked(r);
19737 queue.scheduleBroadcastsLocked();
19740 // There was nobody interested in the broadcast, but we still want to record
19741 // that it happened.
19742 if (intent.getComponent() == null && intent.getPackage() == null
19743 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19744 // This was an implicit broadcast... let's record it for posterity.
19745 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19749 return ActivityManager.BROADCAST_SUCCESS;
19753 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19755 private int getUidFromIntent(Intent intent) {
19756 if (intent == null) {
19759 final Bundle intentExtras = intent.getExtras();
19760 return intent.hasExtra(Intent.EXTRA_UID)
19761 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19764 final void rotateBroadcastStatsIfNeededLocked() {
19765 final long now = SystemClock.elapsedRealtime();
19766 if (mCurBroadcastStats == null ||
19767 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19768 mLastBroadcastStats = mCurBroadcastStats;
19769 if (mLastBroadcastStats != null) {
19770 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19771 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19773 mCurBroadcastStats = new BroadcastStats();
19777 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19778 int skipCount, long dispatchTime) {
19779 rotateBroadcastStatsIfNeededLocked();
19780 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19783 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19784 rotateBroadcastStatsIfNeededLocked();
19785 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19788 final Intent verifyBroadcastLocked(Intent intent) {
19789 // Refuse possible leaked file descriptors
19790 if (intent != null && intent.hasFileDescriptors() == true) {
19791 throw new IllegalArgumentException("File descriptors passed in Intent");
19794 int flags = intent.getFlags();
19796 if (!mProcessesReady) {
19797 // if the caller really truly claims to know what they're doing, go
19798 // ahead and allow the broadcast without launching any receivers
19799 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19800 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19801 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19802 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19803 + " before boot completion");
19804 throw new IllegalStateException("Cannot broadcast before boot completed");
19808 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19809 throw new IllegalArgumentException(
19810 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19813 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19814 switch (Binder.getCallingUid()) {
19819 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19820 + Binder.getCallingUid());
19821 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19829 public final int broadcastIntent(IApplicationThread caller,
19830 Intent intent, String resolvedType, IIntentReceiver resultTo,
19831 int resultCode, String resultData, Bundle resultExtras,
19832 String[] requiredPermissions, int appOp, Bundle bOptions,
19833 boolean serialized, boolean sticky, int userId) {
19834 enforceNotIsolatedCaller("broadcastIntent");
19835 synchronized(this) {
19836 intent = verifyBroadcastLocked(intent);
19838 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19839 final int callingPid = Binder.getCallingPid();
19840 final int callingUid = Binder.getCallingUid();
19841 final long origId = Binder.clearCallingIdentity();
19842 int res = broadcastIntentLocked(callerApp,
19843 callerApp != null ? callerApp.info.packageName : null,
19844 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19845 requiredPermissions, appOp, bOptions, serialized, sticky,
19846 callingPid, callingUid, userId);
19847 Binder.restoreCallingIdentity(origId);
19853 int broadcastIntentInPackage(String packageName, int uid,
19854 Intent intent, String resolvedType, IIntentReceiver resultTo,
19855 int resultCode, String resultData, Bundle resultExtras,
19856 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19858 synchronized(this) {
19859 intent = verifyBroadcastLocked(intent);
19861 final long origId = Binder.clearCallingIdentity();
19862 String[] requiredPermissions = requiredPermission == null ? null
19863 : new String[] {requiredPermission};
19864 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19865 resultTo, resultCode, resultData, resultExtras,
19866 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19867 sticky, -1, uid, userId);
19868 Binder.restoreCallingIdentity(origId);
19873 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19874 // Refuse possible leaked file descriptors
19875 if (intent != null && intent.hasFileDescriptors() == true) {
19876 throw new IllegalArgumentException("File descriptors passed in Intent");
19879 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19880 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19882 synchronized(this) {
19883 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19884 != PackageManager.PERMISSION_GRANTED) {
19885 String msg = "Permission Denial: unbroadcastIntent() from pid="
19886 + Binder.getCallingPid()
19887 + ", uid=" + Binder.getCallingUid()
19888 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19890 throw new SecurityException(msg);
19892 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19893 if (stickies != null) {
19894 ArrayList<Intent> list = stickies.get(intent.getAction());
19895 if (list != null) {
19896 int N = list.size();
19898 for (i=0; i<N; i++) {
19899 if (intent.filterEquals(list.get(i))) {
19904 if (list.size() <= 0) {
19905 stickies.remove(intent.getAction());
19908 if (stickies.size() <= 0) {
19909 mStickyBroadcasts.remove(userId);
19915 void backgroundServicesFinishedLocked(int userId) {
19916 for (BroadcastQueue queue : mBroadcastQueues) {
19917 queue.backgroundServicesFinishedLocked(userId);
19921 public void finishReceiver(IBinder who, int resultCode, String resultData,
19922 Bundle resultExtras, boolean resultAbort, int flags) {
19923 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19925 // Refuse possible leaked file descriptors
19926 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19927 throw new IllegalArgumentException("File descriptors passed in Bundle");
19930 final long origId = Binder.clearCallingIdentity();
19932 boolean doNext = false;
19935 synchronized(this) {
19936 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19937 ? mFgBroadcastQueue : mBgBroadcastQueue;
19938 r = queue.getMatchingOrderedReceiver(who);
19940 doNext = r.queue.finishReceiverLocked(r, resultCode,
19941 resultData, resultExtras, resultAbort, true);
19946 r.queue.processNextBroadcast(false);
19948 trimApplications();
19950 Binder.restoreCallingIdentity(origId);
19954 // =========================================================
19956 // =========================================================
19958 public boolean startInstrumentation(ComponentName className,
19959 String profileFile, int flags, Bundle arguments,
19960 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19961 int userId, String abiOverride) {
19962 enforceNotIsolatedCaller("startInstrumentation");
19963 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19964 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19965 // Refuse possible leaked file descriptors
19966 if (arguments != null && arguments.hasFileDescriptors()) {
19967 throw new IllegalArgumentException("File descriptors passed in Bundle");
19970 synchronized(this) {
19971 InstrumentationInfo ii = null;
19972 ApplicationInfo ai = null;
19974 ii = mContext.getPackageManager().getInstrumentationInfo(
19975 className, STOCK_PM_FLAGS);
19976 ai = AppGlobals.getPackageManager().getApplicationInfo(
19977 ii.targetPackage, STOCK_PM_FLAGS, userId);
19978 } catch (PackageManager.NameNotFoundException e) {
19979 } catch (RemoteException e) {
19982 reportStartInstrumentationFailureLocked(watcher, className,
19983 "Unable to find instrumentation info for: " + className);
19987 reportStartInstrumentationFailureLocked(watcher, className,
19988 "Unable to find instrumentation target package: " + ii.targetPackage);
19991 if (!ai.hasCode()) {
19992 reportStartInstrumentationFailureLocked(watcher, className,
19993 "Instrumentation target has no code: " + ii.targetPackage);
19997 int match = mContext.getPackageManager().checkSignatures(
19998 ii.targetPackage, ii.packageName);
19999 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20000 String msg = "Permission Denial: starting instrumentation "
20001 + className + " from pid="
20002 + Binder.getCallingPid()
20003 + ", uid=" + Binder.getCallingPid()
20004 + " not allowed because package " + ii.packageName
20005 + " does not have a signature matching the target "
20006 + ii.targetPackage;
20007 reportStartInstrumentationFailureLocked(watcher, className, msg);
20008 throw new SecurityException(msg);
20011 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20012 activeInstr.mClass = className;
20013 String defProcess = ai.processName;;
20014 if (ii.targetProcesses == null) {
20015 activeInstr.mTargetProcesses = new String[]{ai.processName};
20016 } else if (ii.targetProcesses.equals("*")) {
20017 activeInstr.mTargetProcesses = new String[0];
20019 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20020 defProcess = activeInstr.mTargetProcesses[0];
20022 activeInstr.mTargetInfo = ai;
20023 activeInstr.mProfileFile = profileFile;
20024 activeInstr.mArguments = arguments;
20025 activeInstr.mWatcher = watcher;
20026 activeInstr.mUiAutomationConnection = uiAutomationConnection;
20027 activeInstr.mResultClass = className;
20029 final long origId = Binder.clearCallingIdentity();
20030 // Instrumentation can kill and relaunch even persistent processes
20031 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20033 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20034 app.instr = activeInstr;
20035 activeInstr.mFinished = false;
20036 activeInstr.mRunningProcesses.add(app);
20037 if (!mActiveInstrumentation.contains(activeInstr)) {
20038 mActiveInstrumentation.add(activeInstr);
20040 Binder.restoreCallingIdentity(origId);
20047 * Report errors that occur while attempting to start Instrumentation. Always writes the
20048 * error to the logs, but if somebody is watching, send the report there too. This enables
20049 * the "am" command to report errors with more information.
20051 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
20052 * @param cn The component name of the instrumentation.
20053 * @param report The error report.
20055 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20056 ComponentName cn, String report) {
20057 Slog.w(TAG, report);
20058 if (watcher != null) {
20059 Bundle results = new Bundle();
20060 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20061 results.putString("Error", report);
20062 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20066 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20067 if (app.instr == null) {
20068 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20072 if (!app.instr.mFinished && results != null) {
20073 if (app.instr.mCurResults == null) {
20074 app.instr.mCurResults = new Bundle(results);
20076 app.instr.mCurResults.putAll(results);
20081 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20082 int userId = UserHandle.getCallingUserId();
20083 // Refuse possible leaked file descriptors
20084 if (results != null && results.hasFileDescriptors()) {
20085 throw new IllegalArgumentException("File descriptors passed in Intent");
20088 synchronized(this) {
20089 ProcessRecord app = getRecordForAppLocked(target);
20091 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20094 final long origId = Binder.clearCallingIdentity();
20095 addInstrumentationResultsLocked(app, results);
20096 Binder.restoreCallingIdentity(origId);
20100 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20101 if (app.instr == null) {
20102 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20106 if (!app.instr.mFinished) {
20107 if (app.instr.mWatcher != null) {
20108 Bundle finalResults = app.instr.mCurResults;
20109 if (finalResults != null) {
20110 if (app.instr.mCurResults != null && results != null) {
20111 finalResults.putAll(results);
20114 finalResults = results;
20116 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20117 app.instr.mClass, resultCode, finalResults);
20120 // Can't call out of the system process with a lock held, so post a message.
20121 if (app.instr.mUiAutomationConnection != null) {
20122 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20123 app.instr.mUiAutomationConnection).sendToTarget();
20125 app.instr.mFinished = true;
20128 app.instr.removeProcess(app);
20131 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20135 public void finishInstrumentation(IApplicationThread target,
20136 int resultCode, Bundle results) {
20137 int userId = UserHandle.getCallingUserId();
20138 // Refuse possible leaked file descriptors
20139 if (results != null && results.hasFileDescriptors()) {
20140 throw new IllegalArgumentException("File descriptors passed in Intent");
20143 synchronized(this) {
20144 ProcessRecord app = getRecordForAppLocked(target);
20146 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20149 final long origId = Binder.clearCallingIdentity();
20150 finishInstrumentationLocked(app, resultCode, results);
20151 Binder.restoreCallingIdentity(origId);
20155 // =========================================================
20157 // =========================================================
20159 public ConfigurationInfo getDeviceConfigurationInfo() {
20160 ConfigurationInfo config = new ConfigurationInfo();
20161 synchronized (this) {
20162 final Configuration globalConfig = getGlobalConfiguration();
20163 config.reqTouchScreen = globalConfig.touchscreen;
20164 config.reqKeyboardType = globalConfig.keyboard;
20165 config.reqNavigation = globalConfig.navigation;
20166 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20167 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20168 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20170 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20171 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20172 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20174 config.reqGlEsVersion = GL_ES_VERSION;
20179 ActivityStack getFocusedStack() {
20180 return mStackSupervisor.getFocusedStack();
20184 public int getFocusedStackId() throws RemoteException {
20185 ActivityStack focusedStack = getFocusedStack();
20186 if (focusedStack != null) {
20187 return focusedStack.getStackId();
20192 public Configuration getConfiguration() {
20194 synchronized(this) {
20195 ci = new Configuration(getGlobalConfiguration());
20196 ci.userSetLocale = false;
20202 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20203 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20204 synchronized (this) {
20205 mSuppressResizeConfigChanges = suppress;
20210 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20211 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20212 * activity and clearing the task at the same time.
20215 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20216 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20217 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20218 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20220 synchronized (this) {
20221 final long origId = Binder.clearCallingIdentity();
20223 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20225 Binder.restoreCallingIdentity(origId);
20231 public void updatePersistentConfiguration(Configuration values) {
20232 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20233 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20234 if (values == null) {
20235 throw new NullPointerException("Configuration must not be null");
20238 int userId = UserHandle.getCallingUserId();
20240 synchronized(this) {
20241 updatePersistentConfigurationLocked(values, userId);
20245 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20246 final long origId = Binder.clearCallingIdentity();
20248 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20250 Binder.restoreCallingIdentity(origId);
20254 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20255 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20256 FONT_SCALE, 1.0f, userId);
20258 synchronized (this) {
20259 if (getGlobalConfiguration().fontScale == scaleFactor) {
20263 final Configuration configuration
20264 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20265 configuration.fontScale = scaleFactor;
20266 updatePersistentConfigurationLocked(configuration, userId);
20270 private void enforceWriteSettingsPermission(String func) {
20271 int uid = Binder.getCallingUid();
20272 if (uid == ROOT_UID) {
20276 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20277 Settings.getPackageNameForUid(mContext, uid), false)) {
20281 String msg = "Permission Denial: " + func + " from pid="
20282 + Binder.getCallingPid()
20284 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20286 throw new SecurityException(msg);
20290 public boolean updateConfiguration(Configuration values) {
20291 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20293 synchronized(this) {
20294 if (values == null && mWindowManager != null) {
20295 // sentinel: fetch the current configuration from the window manager
20296 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20299 if (mWindowManager != null) {
20300 // Update OOM levels based on display size.
20301 mProcessList.applyDisplaySize(mWindowManager);
20304 final long origId = Binder.clearCallingIdentity();
20306 if (values != null) {
20307 Settings.System.clearConfiguration(values);
20309 updateConfigurationLocked(values, null, false, false /* persistent */,
20310 UserHandle.USER_NULL, false /* deferResume */,
20311 mTmpUpdateConfigurationResult);
20312 return mTmpUpdateConfigurationResult.changes != 0;
20314 Binder.restoreCallingIdentity(origId);
20319 void updateUserConfigurationLocked() {
20320 final Configuration configuration = new Configuration(getGlobalConfiguration());
20321 final int currentUserId = mUserController.getCurrentUserIdLocked();
20322 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20323 currentUserId, Settings.System.canWrite(mContext));
20324 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20325 false /* persistent */, currentUserId, false /* deferResume */);
20328 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20329 boolean initLocale) {
20330 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20333 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20334 boolean initLocale, boolean deferResume) {
20335 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20336 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20337 UserHandle.USER_NULL, deferResume);
20340 // To cache the list of supported system locales
20341 private String[] mSupportedSystemLocales = null;
20343 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20344 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20345 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20346 deferResume, null /* result */);
20350 * Do either or both things: (1) change the current configuration, and (2)
20351 * make sure the given activity is running with the (now) current
20352 * configuration. Returns true if the activity has been left running, or
20353 * false if <var>starting</var> is being destroyed to match the new
20356 * @param userId is only used when persistent parameter is set to true to persist configuration
20357 * for that particular user
20359 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20360 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20361 UpdateConfigurationResult result) {
20363 boolean kept = true;
20365 if (mWindowManager != null) {
20366 mWindowManager.deferSurfaceLayout();
20369 if (values != null) {
20370 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20374 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20376 if (mWindowManager != null) {
20377 mWindowManager.continueSurfaceLayout();
20381 if (result != null) {
20382 result.changes = changes;
20383 result.activityRelaunched = !kept;
20388 /** Update default (global) configuration and notify listeners about changes. */
20389 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20390 boolean persistent, int userId, boolean deferResume) {
20391 mTempConfig.setTo(getGlobalConfiguration());
20392 final int changes = mTempConfig.updateFrom(values);
20393 if (changes == 0) {
20394 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20395 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20396 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20397 // (even if there are no actual changes) to unfreeze the window.
20398 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20402 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20403 "Updating global configuration to: " + values);
20405 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20407 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20408 final LocaleList locales = values.getLocales();
20409 int bestLocaleIndex = 0;
20410 if (locales.size() > 1) {
20411 if (mSupportedSystemLocales == null) {
20412 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20414 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20416 SystemProperties.set("persist.sys.locale",
20417 locales.get(bestLocaleIndex).toLanguageTag());
20418 LocaleList.setDefault(locales, bestLocaleIndex);
20419 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20420 locales.get(bestLocaleIndex)));
20423 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20424 mTempConfig.seq = mConfigurationSeq;
20426 // Update stored global config and notify everyone about the change.
20427 mStackSupervisor.onConfigurationChanged(mTempConfig);
20429 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20430 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20431 mUsageStatsService.reportConfigurationChange(mTempConfig,
20432 mUserController.getCurrentUserIdLocked());
20434 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20435 mShowDialogs = shouldShowDialogs(mTempConfig);
20437 AttributeCache ac = AttributeCache.instance();
20439 ac.updateConfiguration(mTempConfig);
20442 // Make sure all resources in our process are updated right now, so that anyone who is going
20443 // to retrieve resource values after we return will be sure to get the new ones. This is
20444 // especially important during boot, where the first config change needs to guarantee all
20445 // resources have that config before following boot code is executed.
20446 mSystemThread.applyConfigurationToResources(mTempConfig);
20448 // We need another copy of global config because we're scheduling some calls instead of
20449 // running them in place. We need to be sure that object we send will be handled unchanged.
20450 final Configuration configCopy = new Configuration(mTempConfig);
20451 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20452 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20453 msg.obj = configCopy;
20455 mHandler.sendMessage(msg);
20458 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20459 ProcessRecord app = mLruProcesses.get(i);
20461 if (app.thread != null) {
20462 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20463 + app.processName + " new config " + configCopy);
20464 app.thread.scheduleConfigurationChanged(configCopy);
20466 } catch (Exception e) {
20470 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20471 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20472 | Intent.FLAG_RECEIVER_FOREGROUND
20473 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20474 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20475 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20476 UserHandle.USER_ALL);
20477 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20478 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20479 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20480 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20481 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20482 if (initLocale || !mProcessesReady) {
20483 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20485 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20486 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20487 UserHandle.USER_ALL);
20490 // Override configuration of the default display duplicates global config, so we need to
20491 // update it also. This will also notify WindowManager about changes.
20492 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20499 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20500 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20502 synchronized (this) {
20503 // Check if display is initialized in AM.
20504 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20505 // Call might come when display is not yet added or has already been removed.
20506 if (DEBUG_CONFIGURATION) {
20507 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20513 if (values == null && mWindowManager != null) {
20514 // sentinel: fetch the current configuration from the window manager
20515 values = mWindowManager.computeNewConfiguration(displayId);
20518 if (mWindowManager != null) {
20519 // Update OOM levels based on display size.
20520 mProcessList.applyDisplaySize(mWindowManager);
20523 final long origId = Binder.clearCallingIdentity();
20525 if (values != null) {
20526 Settings.System.clearConfiguration(values);
20528 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20529 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20530 return mTmpUpdateConfigurationResult.changes != 0;
20532 Binder.restoreCallingIdentity(origId);
20537 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20538 boolean deferResume, int displayId) {
20539 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20540 displayId, null /* result */);
20544 * Updates override configuration specific for the selected display. If no config is provided,
20545 * new one will be computed in WM based on current display info.
20547 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20548 ActivityRecord starting, boolean deferResume, int displayId,
20549 UpdateConfigurationResult result) {
20551 boolean kept = true;
20553 if (mWindowManager != null) {
20554 mWindowManager.deferSurfaceLayout();
20557 if (values != null) {
20558 if (displayId == DEFAULT_DISPLAY) {
20559 // Override configuration of the default display duplicates global config, so
20560 // we're calling global config update instead for default display. It will also
20561 // apply the correct override config.
20562 changes = updateGlobalConfiguration(values, false /* initLocale */,
20563 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20565 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20569 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20571 if (mWindowManager != null) {
20572 mWindowManager.continueSurfaceLayout();
20576 if (result != null) {
20577 result.changes = changes;
20578 result.activityRelaunched = !kept;
20583 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20585 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20586 final int changes = mTempConfig.updateFrom(values);
20587 if (changes != 0) {
20588 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20589 + mTempConfig + " for displayId=" + displayId);
20590 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20592 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20593 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20594 // Reset the unsupported display size dialog.
20595 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20597 killAllBackgroundProcessesExcept(N,
20598 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20602 // Update the configuration with WM first and check if any of the stacks need to be resized
20603 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20604 // necessary. This way we don't need to relaunch again afterwards in
20605 // ensureActivityConfigurationLocked().
20606 if (mWindowManager != null) {
20607 final int[] resizedStacks =
20608 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20609 if (resizedStacks != null) {
20610 for (int stackId : resizedStacks) {
20611 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20619 /** Applies latest configuration and/or visibility updates if needed. */
20620 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20621 boolean kept = true;
20622 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20623 // mainStack is null during startup.
20624 if (mainStack != null) {
20625 if (changes != 0 && starting == null) {
20626 // If the configuration changed, and the caller is not already
20627 // in the process of starting an activity, then find the top
20628 // activity to check if its configuration needs to change.
20629 starting = mainStack.topRunningActivityLocked();
20632 if (starting != null) {
20633 kept = starting.ensureActivityConfigurationLocked(changes,
20634 false /* preserveWindow */);
20635 // And we need to make sure at this point that all other activities
20636 // are made visible with the correct configuration.
20637 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20638 !PRESERVE_WINDOWS);
20645 /** Helper method that requests bounds from WM and applies them to stack. */
20646 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20647 final Rect newStackBounds = new Rect();
20648 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20649 mStackSupervisor.resizeStackLocked(
20650 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20651 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20652 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20656 * Decide based on the configuration whether we should show the ANR,
20657 * crash, etc dialogs. The idea is that if there is no affordance to
20658 * press the on-screen buttons, or the user experience would be more
20659 * greatly impacted than the crash itself, we shouldn't show the dialog.
20661 * A thought: SystemUI might also want to get told about this, the Power
20662 * dialog / global actions also might want different behaviors.
20664 private static boolean shouldShowDialogs(Configuration config) {
20665 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20666 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20667 && config.navigation == Configuration.NAVIGATION_NONAV);
20668 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20669 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20670 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20671 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20672 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20673 return inputMethodExists && uiModeSupportsDialogs;
20677 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20678 synchronized (this) {
20679 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20680 if (srec != null) {
20681 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20687 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20688 Intent resultData) {
20690 synchronized (this) {
20691 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20693 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20699 public int getLaunchedFromUid(IBinder activityToken) {
20700 ActivityRecord srec;
20701 synchronized (this) {
20702 srec = ActivityRecord.forTokenLocked(activityToken);
20704 if (srec == null) {
20707 return srec.launchedFromUid;
20710 public String getLaunchedFromPackage(IBinder activityToken) {
20711 ActivityRecord srec;
20712 synchronized (this) {
20713 srec = ActivityRecord.forTokenLocked(activityToken);
20715 if (srec == null) {
20718 return srec.launchedFromPackage;
20721 // =========================================================
20722 // LIFETIME MANAGEMENT
20723 // =========================================================
20725 // Returns whether the app is receiving broadcast.
20726 // If receiving, fetch all broadcast queues which the app is
20727 // the current [or imminent] receiver on.
20728 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20729 ArraySet<BroadcastQueue> receivingQueues) {
20730 if (!app.curReceivers.isEmpty()) {
20731 for (BroadcastRecord r : app.curReceivers) {
20732 receivingQueues.add(r.queue);
20737 // It's not the current receiver, but it might be starting up to become one
20738 for (BroadcastQueue queue : mBroadcastQueues) {
20739 final BroadcastRecord r = queue.mPendingBroadcast;
20740 if (r != null && r.curApp == app) {
20741 // found it; report which queue it's in
20742 receivingQueues.add(queue);
20746 return !receivingQueues.isEmpty();
20749 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20750 int targetUid, ComponentName targetComponent, String targetProcess) {
20751 if (!mTrackingAssociations) {
20754 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20755 = mAssociations.get(targetUid);
20756 if (components == null) {
20757 components = new ArrayMap<>();
20758 mAssociations.put(targetUid, components);
20760 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20761 if (sourceUids == null) {
20762 sourceUids = new SparseArray<>();
20763 components.put(targetComponent, sourceUids);
20765 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20766 if (sourceProcesses == null) {
20767 sourceProcesses = new ArrayMap<>();
20768 sourceUids.put(sourceUid, sourceProcesses);
20770 Association ass = sourceProcesses.get(sourceProcess);
20772 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20774 sourceProcesses.put(sourceProcess, ass);
20778 if (ass.mNesting == 1) {
20779 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20780 ass.mLastState = sourceState;
20785 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20786 ComponentName targetComponent) {
20787 if (!mTrackingAssociations) {
20790 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20791 = mAssociations.get(targetUid);
20792 if (components == null) {
20795 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20796 if (sourceUids == null) {
20799 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20800 if (sourceProcesses == null) {
20803 Association ass = sourceProcesses.get(sourceProcess);
20804 if (ass == null || ass.mNesting <= 0) {
20808 if (ass.mNesting == 0) {
20809 long uptime = SystemClock.uptimeMillis();
20810 ass.mTime += uptime - ass.mStartTime;
20811 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20812 += uptime - ass.mLastStateUptime;
20813 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20817 private void noteUidProcessState(final int uid, final int state) {
20818 mBatteryStatsService.noteUidProcessState(uid, state);
20819 if (mTrackingAssociations) {
20820 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20821 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20822 = mAssociations.valueAt(i1);
20823 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20824 SparseArray<ArrayMap<String, Association>> sourceUids
20825 = targetComponents.valueAt(i2);
20826 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20827 if (sourceProcesses != null) {
20828 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20829 Association ass = sourceProcesses.valueAt(i4);
20830 if (ass.mNesting >= 1) {
20831 // currently associated
20832 long uptime = SystemClock.uptimeMillis();
20833 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20834 += uptime - ass.mLastStateUptime;
20835 ass.mLastState = state;
20836 ass.mLastStateUptime = uptime;
20845 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20846 boolean doingAll, long now) {
20847 if (mAdjSeq == app.adjSeq) {
20848 // This adjustment has already been computed.
20849 return app.curRawAdj;
20852 if (app.thread == null) {
20853 app.adjSeq = mAdjSeq;
20854 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20855 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20856 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20859 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20860 app.adjSource = null;
20861 app.adjTarget = null;
20863 app.cached = false;
20865 final int activitiesSize = app.activities.size();
20867 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20868 // The max adjustment doesn't allow this app to be anything
20869 // below foreground, so it is not worth doing work for it.
20870 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20871 app.adjType = "fixed";
20872 app.adjSeq = mAdjSeq;
20873 app.curRawAdj = app.maxAdj;
20874 app.foregroundActivities = false;
20875 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20876 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20877 // System processes can do UI, and when they do we want to have
20878 // them trim their memory after the user leaves the UI. To
20879 // facilitate this, here we need to determine whether or not it
20880 // is currently showing UI.
20881 app.systemNoUi = true;
20882 if (app == TOP_APP) {
20883 app.systemNoUi = false;
20884 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20885 app.adjType = "pers-top-activity";
20886 } else if (app.hasTopUi) {
20887 app.systemNoUi = false;
20888 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20889 app.adjType = "pers-top-ui";
20890 } else if (activitiesSize > 0) {
20891 for (int j = 0; j < activitiesSize; j++) {
20892 final ActivityRecord r = app.activities.get(j);
20894 app.systemNoUi = false;
20898 if (!app.systemNoUi) {
20899 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20901 return (app.curAdj=app.maxAdj);
20904 app.systemNoUi = false;
20906 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20908 // Determine the importance of the process, starting with most
20909 // important to least, and assign an appropriate OOM adjustment.
20913 boolean foregroundActivities = false;
20914 mTmpBroadcastQueue.clear();
20915 if (app == TOP_APP) {
20916 // The last app on the list is the foreground app.
20917 adj = ProcessList.FOREGROUND_APP_ADJ;
20918 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20919 app.adjType = "top-activity";
20920 foregroundActivities = true;
20921 procState = PROCESS_STATE_CUR_TOP;
20922 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20923 } else if (app.instr != null) {
20924 // Don't want to kill running instrumentation.
20925 adj = ProcessList.FOREGROUND_APP_ADJ;
20926 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20927 app.adjType = "instrumentation";
20928 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20929 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20930 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20931 // An app that is currently receiving a broadcast also
20932 // counts as being in the foreground for OOM killer purposes.
20933 // It's placed in a sched group based on the nature of the
20934 // broadcast as reflected by which queue it's active in.
20935 adj = ProcessList.FOREGROUND_APP_ADJ;
20936 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20937 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20938 app.adjType = "broadcast";
20939 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20940 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20941 } else if (app.executingServices.size() > 0) {
20942 // An app that is currently executing a service callback also
20943 // counts as being in the foreground.
20944 adj = ProcessList.FOREGROUND_APP_ADJ;
20945 schedGroup = app.execServicesFg ?
20946 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20947 app.adjType = "exec-service";
20948 procState = ActivityManager.PROCESS_STATE_SERVICE;
20949 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20950 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20952 // As far as we know the process is empty. We may change our mind later.
20953 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20954 // At this point we don't actually know the adjustment. Use the cached adj
20955 // value that the caller wants us to.
20957 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20960 app.adjType = "cch-empty";
20961 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20964 // Examine all activities if not already foreground.
20965 if (!foregroundActivities && activitiesSize > 0) {
20966 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20967 for (int j = 0; j < activitiesSize; j++) {
20968 final ActivityRecord r = app.activities.get(j);
20969 if (r.app != app) {
20970 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20971 + " instead of expected " + app);
20972 if (r.app == null || (r.app.uid == app.uid)) {
20973 // Only fix things up when they look sane
20980 // App has a visible activity; only upgrade adjustment.
20981 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20982 adj = ProcessList.VISIBLE_APP_ADJ;
20983 app.adjType = "vis-activity";
20984 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20986 if (procState > PROCESS_STATE_CUR_TOP) {
20987 procState = PROCESS_STATE_CUR_TOP;
20988 app.adjType = "vis-activity";
20989 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20991 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20992 app.cached = false;
20994 foregroundActivities = true;
20995 final TaskRecord task = r.getTask();
20996 if (task != null && minLayer > 0) {
20997 final int layer = task.mLayerRank;
20998 if (layer >= 0 && minLayer > layer) {
21003 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21004 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21005 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21006 app.adjType = "pause-activity";
21007 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21009 if (procState > PROCESS_STATE_CUR_TOP) {
21010 procState = PROCESS_STATE_CUR_TOP;
21011 app.adjType = "pause-activity";
21012 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21014 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21015 app.cached = false;
21017 foregroundActivities = true;
21018 } else if (r.state == ActivityState.STOPPING) {
21019 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21020 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21021 app.adjType = "stop-activity";
21022 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21024 // For the process state, we will at this point consider the
21025 // process to be cached. It will be cached either as an activity
21026 // or empty depending on whether the activity is finishing. We do
21027 // this so that we can treat the process as cached for purposes of
21028 // memory trimming (determing current memory level, trim command to
21029 // send to process) since there can be an arbitrary number of stopping
21030 // processes and they should soon all go into the cached state.
21031 if (!r.finishing) {
21032 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21033 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21034 app.adjType = "stop-activity";
21035 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21038 app.cached = false;
21040 foregroundActivities = true;
21042 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21043 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21044 app.adjType = "cch-act";
21045 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21049 if (adj == ProcessList.VISIBLE_APP_ADJ) {
21054 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21055 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21056 if (app.foregroundServices) {
21057 // The user is aware of this app, so make it visible.
21058 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21059 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21060 app.cached = false;
21061 app.adjType = "fg-service";
21062 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21063 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21064 } else if (app.hasOverlayUi) {
21065 // The process is display an overlay UI.
21066 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21067 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21068 app.cached = false;
21069 app.adjType = "has-overlay-ui";
21070 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21071 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21075 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21076 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21077 if (app.forcingToImportant != null) {
21078 // This is currently used for toasts... they are not interactive, and
21079 // we don't want them to cause the app to become fully foreground (and
21080 // thus out of background check), so we yes the best background level we can.
21081 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21082 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21083 app.cached = false;
21084 app.adjType = "force-imp";
21085 app.adjSource = app.forcingToImportant;
21086 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21087 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21091 if (app == mHeavyWeightProcess) {
21092 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21093 // We don't want to kill the current heavy-weight process.
21094 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21095 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21096 app.cached = false;
21097 app.adjType = "heavy";
21098 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21100 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21101 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21102 app.adjType = "heavy";
21103 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21107 if (app == mHomeProcess) {
21108 if (adj > ProcessList.HOME_APP_ADJ) {
21109 // This process is hosting what we currently consider to be the
21110 // home app, so we don't want to let it go into the background.
21111 adj = ProcessList.HOME_APP_ADJ;
21112 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21113 app.cached = false;
21114 app.adjType = "home";
21115 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21117 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21118 procState = ActivityManager.PROCESS_STATE_HOME;
21119 app.adjType = "home";
21120 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21124 if (app == mPreviousProcess && app.activities.size() > 0) {
21125 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21126 // This was the previous process that showed UI to the user.
21127 // We want to try to keep it around more aggressively, to give
21128 // a good experience around switching between two apps.
21129 adj = ProcessList.PREVIOUS_APP_ADJ;
21130 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21131 app.cached = false;
21132 app.adjType = "previous";
21133 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21135 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21136 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21137 app.adjType = "previous";
21138 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21142 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21143 + " reason=" + app.adjType);
21145 // By default, we use the computed adjustment. It may be changed if
21146 // there are applications dependent on our services or providers, but
21147 // this gives us a baseline and makes sure we don't get into an
21148 // infinite recursion.
21149 app.adjSeq = mAdjSeq;
21150 app.curRawAdj = adj;
21151 app.hasStartedServices = false;
21153 if (mBackupTarget != null && app == mBackupTarget.app) {
21154 // If possible we want to avoid killing apps while they're being backed up
21155 if (adj > ProcessList.BACKUP_APP_ADJ) {
21156 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21157 adj = ProcessList.BACKUP_APP_ADJ;
21158 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21159 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21161 app.adjType = "backup";
21162 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21163 app.cached = false;
21165 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21166 procState = ActivityManager.PROCESS_STATE_BACKUP;
21167 app.adjType = "backup";
21168 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21172 boolean mayBeTop = false;
21173 String mayBeTopType = null;
21174 Object mayBeTopSource = null;
21175 Object mayBeTopTarget = null;
21177 for (int is = app.services.size()-1;
21178 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21179 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21180 || procState > ActivityManager.PROCESS_STATE_TOP);
21182 ServiceRecord s = app.services.valueAt(is);
21183 if (s.startRequested) {
21184 app.hasStartedServices = true;
21185 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21186 procState = ActivityManager.PROCESS_STATE_SERVICE;
21187 app.adjType = "started-services";
21188 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21190 if (app.hasShownUi && app != mHomeProcess) {
21191 // If this process has shown some UI, let it immediately
21192 // go to the LRU list because it may be pretty heavy with
21193 // UI stuff. We'll tag it with a label just to help
21194 // debug and understand what is going on.
21195 if (adj > ProcessList.SERVICE_ADJ) {
21196 app.adjType = "cch-started-ui-services";
21199 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21200 // This service has seen some activity within
21201 // recent memory, so we will keep its process ahead
21202 // of the background processes.
21203 if (adj > ProcessList.SERVICE_ADJ) {
21204 adj = ProcessList.SERVICE_ADJ;
21205 app.adjType = "started-services";
21206 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21207 app.cached = false;
21210 // If we have let the service slide into the background
21211 // state, still have some text describing what it is doing
21212 // even though the service no longer has an impact.
21213 if (adj > ProcessList.SERVICE_ADJ) {
21214 app.adjType = "cch-started-services";
21219 for (int conni = s.connections.size()-1;
21220 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21221 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21222 || procState > ActivityManager.PROCESS_STATE_TOP);
21224 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21226 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21227 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21228 || procState > ActivityManager.PROCESS_STATE_TOP);
21230 // XXX should compute this based on the max of
21231 // all connected clients.
21232 ConnectionRecord cr = clist.get(i);
21233 if (cr.binding.client == app) {
21234 // Binding to ourself is not interesting.
21238 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21239 ProcessRecord client = cr.binding.client;
21240 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21241 TOP_APP, doingAll, now);
21242 int clientProcState = client.curProcState;
21243 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21244 // If the other app is cached for any reason, for purposes here
21245 // we are going to consider it empty. The specific cached state
21246 // doesn't propagate except under certain conditions.
21247 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21249 String adjType = null;
21250 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21251 // Not doing bind OOM management, so treat
21252 // this guy more like a started service.
21253 if (app.hasShownUi && app != mHomeProcess) {
21254 // If this process has shown some UI, let it immediately
21255 // go to the LRU list because it may be pretty heavy with
21256 // UI stuff. We'll tag it with a label just to help
21257 // debug and understand what is going on.
21258 if (adj > clientAdj) {
21259 adjType = "cch-bound-ui-services";
21261 app.cached = false;
21263 clientProcState = procState;
21265 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21266 // This service has not seen activity within
21267 // recent memory, so allow it to drop to the
21268 // LRU list if there is no other reason to keep
21269 // it around. We'll also tag it with a label just
21270 // to help debug and undertand what is going on.
21271 if (adj > clientAdj) {
21272 adjType = "cch-bound-services";
21278 if (adj > clientAdj) {
21279 // If this process has recently shown UI, and
21280 // the process that is binding to it is less
21281 // important than being visible, then we don't
21282 // care about the binding as much as we care
21283 // about letting this process get into the LRU
21284 // list to be killed and restarted if needed for
21286 if (app.hasShownUi && app != mHomeProcess
21287 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21288 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21289 adjType = "cch-bound-ui-services";
21293 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21294 |Context.BIND_IMPORTANT)) != 0) {
21295 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21296 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21297 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21298 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21299 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21300 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21301 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21302 newAdj = clientAdj;
21304 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21305 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21310 if (!client.cached) {
21311 app.cached = false;
21313 if (adj > newAdj) {
21315 adjType = "service";
21319 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21320 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21321 // This will treat important bound services identically to
21322 // the top app, which may behave differently than generic
21323 // foreground work.
21324 if (client.curSchedGroup > schedGroup) {
21325 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21326 schedGroup = client.curSchedGroup;
21328 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21331 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21332 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21333 // Special handling of clients who are in the top state.
21334 // We *may* want to consider this process to be in the
21335 // top state as well, but only if there is not another
21336 // reason for it to be running. Being on the top is a
21337 // special state, meaning you are specifically running
21338 // for the current top app. If the process is already
21339 // running in the background for some other reason, it
21340 // is more important to continue considering it to be
21341 // in the background state.
21343 mayBeTopType = "service";
21344 mayBeTopSource = cr.binding.client;
21345 mayBeTopTarget = s.name;
21346 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21348 // Special handling for above-top states (persistent
21349 // processes). These should not bring the current process
21350 // into the top state, since they are not on top. Instead
21351 // give them the best state after that.
21352 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21354 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21355 } else if (mWakefulness
21356 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21357 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21360 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21363 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21367 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21368 if (clientProcState <
21369 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21371 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21374 if (clientProcState <
21375 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21377 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21380 if (procState > clientProcState) {
21381 procState = clientProcState;
21382 if (adjType == null) {
21383 adjType = "service";
21386 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21387 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21388 app.pendingUiClean = true;
21390 if (adjType != null) {
21391 app.adjType = adjType;
21392 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21393 .REASON_SERVICE_IN_USE;
21394 app.adjSource = cr.binding.client;
21395 app.adjSourceProcState = clientProcState;
21396 app.adjTarget = s.name;
21397 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21398 + ": " + app + ", due to " + cr.binding.client
21399 + " adj=" + adj + " procState=" + procState);
21402 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21403 app.treatLikeActivity = true;
21405 final ActivityRecord a = cr.activity;
21406 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21407 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21408 (a.visible || a.state == ActivityState.RESUMED ||
21409 a.state == ActivityState.PAUSING)) {
21410 adj = ProcessList.FOREGROUND_APP_ADJ;
21411 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21412 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21413 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21415 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21418 app.cached = false;
21419 app.adjType = "service";
21420 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21421 .REASON_SERVICE_IN_USE;
21423 app.adjSourceProcState = procState;
21424 app.adjTarget = s.name;
21425 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21433 for (int provi = app.pubProviders.size()-1;
21434 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21435 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21436 || procState > ActivityManager.PROCESS_STATE_TOP);
21438 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21439 for (int i = cpr.connections.size()-1;
21440 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21441 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21442 || procState > ActivityManager.PROCESS_STATE_TOP);
21444 ContentProviderConnection conn = cpr.connections.get(i);
21445 ProcessRecord client = conn.client;
21446 if (client == app) {
21447 // Being our own client is not interesting.
21450 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21451 int clientProcState = client.curProcState;
21452 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21453 // If the other app is cached for any reason, for purposes here
21454 // we are going to consider it empty.
21455 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21457 String adjType = null;
21458 if (adj > clientAdj) {
21459 if (app.hasShownUi && app != mHomeProcess
21460 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21461 adjType = "cch-ui-provider";
21463 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21464 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21465 adjType = "provider";
21467 app.cached &= client.cached;
21469 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21470 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21471 // Special handling of clients who are in the top state.
21472 // We *may* want to consider this process to be in the
21473 // top state as well, but only if there is not another
21474 // reason for it to be running. Being on the top is a
21475 // special state, meaning you are specifically running
21476 // for the current top app. If the process is already
21477 // running in the background for some other reason, it
21478 // is more important to continue considering it to be
21479 // in the background state.
21481 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21482 mayBeTopType = adjType = "provider-top";
21483 mayBeTopSource = client;
21484 mayBeTopTarget = cpr.name;
21486 // Special handling for above-top states (persistent
21487 // processes). These should not bring the current process
21488 // into the top state, since they are not on top. Instead
21489 // give them the best state after that.
21491 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21492 if (adjType == null) {
21493 adjType = "provider";
21497 if (procState > clientProcState) {
21498 procState = clientProcState;
21500 if (client.curSchedGroup > schedGroup) {
21501 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21503 if (adjType != null) {
21504 app.adjType = adjType;
21505 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21506 .REASON_PROVIDER_IN_USE;
21507 app.adjSource = client;
21508 app.adjSourceProcState = clientProcState;
21509 app.adjTarget = cpr.name;
21510 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21511 + ": " + app + ", due to " + client
21512 + " adj=" + adj + " procState=" + procState);
21515 // If the provider has external (non-framework) process
21516 // dependencies, ensure that its adjustment is at least
21517 // FOREGROUND_APP_ADJ.
21518 if (cpr.hasExternalProcessHandles()) {
21519 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21520 adj = ProcessList.FOREGROUND_APP_ADJ;
21521 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21522 app.cached = false;
21523 app.adjType = "ext-provider";
21524 app.adjTarget = cpr.name;
21525 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21527 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21528 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21533 if (app.lastProviderTime > 0 &&
21534 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21535 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21536 adj = ProcessList.PREVIOUS_APP_ADJ;
21537 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21538 app.cached = false;
21539 app.adjType = "recent-provider";
21540 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21542 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21543 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21544 app.adjType = "recent-provider";
21545 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21549 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21550 // A client of one of our services or providers is in the top state. We
21551 // *may* want to be in the top state, but not if we are already running in
21552 // the background for some other reason. For the decision here, we are going
21553 // to pick out a few specific states that we want to remain in when a client
21554 // is top (states that tend to be longer-term) and otherwise allow it to go
21555 // to the top state.
21556 switch (procState) {
21557 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21558 // Something else is keeping it at this level, just leave it.
21560 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21561 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21562 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21563 case ActivityManager.PROCESS_STATE_SERVICE:
21564 // These all are longer-term states, so pull them up to the top
21565 // of the background states, but not all the way to the top state.
21566 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21567 app.adjType = mayBeTopType;
21568 app.adjSource = mayBeTopSource;
21569 app.adjTarget = mayBeTopTarget;
21570 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21571 + ": " + app + ", due to " + mayBeTopSource
21572 + " adj=" + adj + " procState=" + procState);
21575 // Otherwise, top is a better choice, so take it.
21576 procState = ActivityManager.PROCESS_STATE_TOP;
21577 app.adjType = mayBeTopType;
21578 app.adjSource = mayBeTopSource;
21579 app.adjTarget = mayBeTopTarget;
21580 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21581 + ": " + app + ", due to " + mayBeTopSource
21582 + " adj=" + adj + " procState=" + procState);
21587 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21588 if (app.hasClientActivities) {
21589 // This is a cached process, but with client activities. Mark it so.
21590 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21591 app.adjType = "cch-client-act";
21592 } else if (app.treatLikeActivity) {
21593 // This is a cached process, but somebody wants us to treat it like it has
21594 // an activity, okay!
21595 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21596 app.adjType = "cch-as-act";
21600 if (adj == ProcessList.SERVICE_ADJ) {
21602 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21603 mNewNumServiceProcs++;
21604 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21605 if (!app.serviceb) {
21606 // This service isn't far enough down on the LRU list to
21607 // normally be a B service, but if we are low on RAM and it
21608 // is large we want to force it down since we would prefer to
21609 // keep launcher over it.
21610 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21611 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21612 app.serviceHighRam = true;
21613 app.serviceb = true;
21614 //Slog.i(TAG, "ADJ " + app + " high ram!");
21616 mNewNumAServiceProcs++;
21617 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21620 app.serviceHighRam = false;
21623 if (app.serviceb) {
21624 adj = ProcessList.SERVICE_B_ADJ;
21628 app.curRawAdj = adj;
21630 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21631 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21632 if (adj > app.maxAdj) {
21634 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21635 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21639 // Do final modification to adj. Everything we do between here and applying
21640 // the final setAdj must be done in this function, because we will also use
21641 // it when computing the final cached adj later. Note that we don't need to
21642 // worry about this for max adj above, since max adj will always be used to
21643 // keep it out of the cached vaues.
21644 app.curAdj = app.modifyRawOomAdj(adj);
21645 app.curSchedGroup = schedGroup;
21646 app.curProcState = procState;
21647 app.foregroundActivities = foregroundActivities;
21649 return app.curRawAdj;
21653 * Record new PSS sample for a process.
21655 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21657 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21659 proc.lastPssTime = now;
21660 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21661 if (DEBUG_PSS) Slog.d(TAG_PSS,
21662 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21663 + " state=" + ProcessList.makeProcStateString(procState));
21664 if (proc.initialIdlePss == 0) {
21665 proc.initialIdlePss = pss;
21667 proc.lastPss = pss;
21668 proc.lastSwapPss = swapPss;
21669 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21670 proc.lastCachedPss = pss;
21671 proc.lastCachedSwapPss = swapPss;
21674 final SparseArray<Pair<Long, String>> watchUids
21675 = mMemWatchProcesses.getMap().get(proc.processName);
21677 if (watchUids != null) {
21678 Pair<Long, String> val = watchUids.get(proc.uid);
21680 val = watchUids.get(0);
21686 if (check != null) {
21687 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21688 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21689 if (!isDebuggable) {
21690 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21691 isDebuggable = true;
21694 if (isDebuggable) {
21695 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21696 final ProcessRecord myProc = proc;
21697 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21698 mMemWatchDumpProcName = proc.processName;
21699 mMemWatchDumpFile = heapdumpFile.toString();
21700 mMemWatchDumpPid = proc.pid;
21701 mMemWatchDumpUid = proc.uid;
21702 BackgroundThread.getHandler().post(new Runnable() {
21704 public void run() {
21705 revokeUriPermission(ActivityThread.currentActivityThread()
21706 .getApplicationThread(),
21707 null, DumpHeapActivity.JAVA_URI,
21708 Intent.FLAG_GRANT_READ_URI_PERMISSION
21709 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21710 UserHandle.myUserId());
21711 ParcelFileDescriptor fd = null;
21713 heapdumpFile.delete();
21714 fd = ParcelFileDescriptor.open(heapdumpFile,
21715 ParcelFileDescriptor.MODE_CREATE |
21716 ParcelFileDescriptor.MODE_TRUNCATE |
21717 ParcelFileDescriptor.MODE_WRITE_ONLY |
21718 ParcelFileDescriptor.MODE_APPEND);
21719 IApplicationThread thread = myProc.thread;
21720 if (thread != null) {
21722 if (DEBUG_PSS) Slog.d(TAG_PSS,
21723 "Requesting dump heap from "
21724 + myProc + " to " + heapdumpFile);
21725 thread.dumpHeap(/* managed= */ true,
21726 /* mallocInfo= */ false, /* runGc= */ false,
21727 heapdumpFile.toString(), fd);
21728 } catch (RemoteException e) {
21731 } catch (FileNotFoundException e) {
21732 e.printStackTrace();
21737 } catch (IOException e) {
21744 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21745 + ", but debugging not enabled");
21752 * Schedule PSS collection of a process.
21754 void requestPssLocked(ProcessRecord proc, int procState) {
21755 if (mPendingPssProcesses.contains(proc)) {
21758 if (mPendingPssProcesses.size() == 0) {
21759 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21761 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21762 proc.pssProcState = procState;
21763 mPendingPssProcesses.add(proc);
21767 * Schedule PSS collection of all processes.
21769 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21771 if (now < (mLastFullPssTime +
21772 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21773 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21777 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21778 mLastFullPssTime = now;
21779 mFullPssPending = true;
21780 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21781 mPendingPssProcesses.clear();
21782 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21783 ProcessRecord app = mLruProcesses.get(i);
21784 if (app.thread == null
21785 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21788 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21789 app.pssProcState = app.setProcState;
21790 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21791 mTestPssMode, isSleepingLocked(), now);
21792 mPendingPssProcesses.add(app);
21795 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21798 public void setTestPssMode(boolean enabled) {
21799 synchronized (this) {
21800 mTestPssMode = enabled;
21802 // Whenever we enable the mode, we want to take a snapshot all of current
21803 // process mem use.
21804 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21810 * Ask a given process to GC right now.
21812 final void performAppGcLocked(ProcessRecord app) {
21814 app.lastRequestedGc = SystemClock.uptimeMillis();
21815 if (app.thread != null) {
21816 if (app.reportLowMemory) {
21817 app.reportLowMemory = false;
21818 app.thread.scheduleLowMemory();
21820 app.thread.processInBackground();
21823 } catch (Exception e) {
21829 * Returns true if things are idle enough to perform GCs.
21831 private final boolean canGcNowLocked() {
21832 boolean processingBroadcasts = false;
21833 for (BroadcastQueue q : mBroadcastQueues) {
21834 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21835 processingBroadcasts = true;
21838 return !processingBroadcasts
21839 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21843 * Perform GCs on all processes that are waiting for it, but only
21844 * if things are idle.
21846 final void performAppGcsLocked() {
21847 final int N = mProcessesToGc.size();
21851 if (canGcNowLocked()) {
21852 while (mProcessesToGc.size() > 0) {
21853 ProcessRecord proc = mProcessesToGc.remove(0);
21854 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21855 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21856 <= SystemClock.uptimeMillis()) {
21857 // To avoid spamming the system, we will GC processes one
21858 // at a time, waiting a few seconds between each.
21859 performAppGcLocked(proc);
21860 scheduleAppGcsLocked();
21863 // It hasn't been long enough since we last GCed this
21864 // process... put it in the list to wait for its time.
21865 addProcessToGcListLocked(proc);
21871 scheduleAppGcsLocked();
21876 * If all looks good, perform GCs on all processes waiting for them.
21878 final void performAppGcsIfAppropriateLocked() {
21879 if (canGcNowLocked()) {
21880 performAppGcsLocked();
21883 // Still not idle, wait some more.
21884 scheduleAppGcsLocked();
21888 * Schedule the execution of all pending app GCs.
21890 final void scheduleAppGcsLocked() {
21891 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21893 if (mProcessesToGc.size() > 0) {
21894 // Schedule a GC for the time to the next process.
21895 ProcessRecord proc = mProcessesToGc.get(0);
21896 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21898 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21899 long now = SystemClock.uptimeMillis();
21900 if (when < (now+mConstants.GC_TIMEOUT)) {
21901 when = now + mConstants.GC_TIMEOUT;
21903 mHandler.sendMessageAtTime(msg, when);
21908 * Add a process to the array of processes waiting to be GCed. Keeps the
21909 * list in sorted order by the last GC time. The process can't already be
21912 final void addProcessToGcListLocked(ProcessRecord proc) {
21913 boolean added = false;
21914 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21915 if (mProcessesToGc.get(i).lastRequestedGc <
21916 proc.lastRequestedGc) {
21918 mProcessesToGc.add(i+1, proc);
21923 mProcessesToGc.add(0, proc);
21928 * Set up to ask a process to GC itself. This will either do it
21929 * immediately, or put it on the list of processes to gc the next
21930 * time things are idle.
21932 final void scheduleAppGcLocked(ProcessRecord app) {
21933 long now = SystemClock.uptimeMillis();
21934 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21937 if (!mProcessesToGc.contains(app)) {
21938 addProcessToGcListLocked(app);
21939 scheduleAppGcsLocked();
21943 final void checkExcessivePowerUsageLocked() {
21944 updateCpuStatsNow();
21946 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21947 boolean doCpuKills = true;
21948 if (mLastPowerCheckUptime == 0) {
21949 doCpuKills = false;
21951 final long curUptime = SystemClock.uptimeMillis();
21952 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21953 mLastPowerCheckUptime = curUptime;
21954 int i = mLruProcesses.size();
21957 ProcessRecord app = mLruProcesses.get(i);
21958 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21959 if (app.lastCpuTime <= 0) {
21962 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21964 StringBuilder sb = new StringBuilder(128);
21965 sb.append("CPU for ");
21966 app.toShortString(sb);
21967 sb.append(": over ");
21968 TimeUtils.formatDuration(uptimeSince, sb);
21969 sb.append(" used ");
21970 TimeUtils.formatDuration(cputimeUsed, sb);
21972 sb.append((cputimeUsed*100)/uptimeSince);
21974 Slog.i(TAG_POWER, sb.toString());
21976 // If the process has used too much CPU over the last duration, the
21977 // user probably doesn't want this, so kill!
21978 if (doCpuKills && uptimeSince > 0) {
21979 // What is the limit for this process?
21981 long checkDur = curUptime - app.whenUnimportant;
21982 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21983 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21984 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21985 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21986 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21987 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21988 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21990 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21992 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21993 synchronized (stats) {
21994 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21995 uptimeSince, cputimeUsed);
21997 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21998 + " dur=" + checkDur + " limit=" + cpuLimit, true);
21999 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22002 app.lastCpuTime = app.curCpuTime;
22007 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22009 boolean success = true;
22011 if (app.curRawAdj != app.setRawAdj) {
22012 app.setRawAdj = app.curRawAdj;
22017 if (app.curAdj != app.setAdj) {
22018 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22019 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22020 String msg = "Set " + app.pid + " " + app.processName + " adj "
22021 + app.curAdj + ": " + app.adjType;
22022 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22024 app.setAdj = app.curAdj;
22025 app.verifiedAdj = ProcessList.INVALID_ADJ;
22028 if (app.setSchedGroup != app.curSchedGroup) {
22029 int oldSchedGroup = app.setSchedGroup;
22030 app.setSchedGroup = app.curSchedGroup;
22031 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22032 String msg = "Setting sched group of " + app.processName
22033 + " to " + app.curSchedGroup;
22034 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22036 if (app.waitingToKill != null && app.curReceivers.isEmpty()
22037 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22038 app.kill(app.waitingToKill, true);
22042 switch (app.curSchedGroup) {
22043 case ProcessList.SCHED_GROUP_BACKGROUND:
22044 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22046 case ProcessList.SCHED_GROUP_TOP_APP:
22047 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22048 processGroup = THREAD_GROUP_TOP_APP;
22051 processGroup = THREAD_GROUP_DEFAULT;
22054 long oldId = Binder.clearCallingIdentity();
22056 setProcessGroup(app.pid, processGroup);
22057 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22058 // do nothing if we already switched to RT
22059 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22060 mVrController.onTopProcChangedLocked(app);
22061 if (mUseFifoUiScheduling) {
22062 // Switch UI pipeline for app to SCHED_FIFO
22063 app.savedPriority = Process.getThreadPriority(app.pid);
22064 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22065 if (app.renderThreadTid != 0) {
22066 scheduleAsFifoPriority(app.renderThreadTid,
22067 /* suppressLogs */true);
22068 if (DEBUG_OOM_ADJ) {
22069 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22070 app.renderThreadTid + ") to FIFO");
22073 if (DEBUG_OOM_ADJ) {
22074 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22078 // Boost priority for top app UI and render threads
22079 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22080 if (app.renderThreadTid != 0) {
22082 setThreadPriority(app.renderThreadTid,
22083 TOP_APP_PRIORITY_BOOST);
22084 } catch (IllegalArgumentException e) {
22085 // thread died, ignore
22090 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22091 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22092 mVrController.onTopProcChangedLocked(app);
22093 if (mUseFifoUiScheduling) {
22095 // Reset UI pipeline to SCHED_OTHER
22096 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22097 setThreadPriority(app.pid, app.savedPriority);
22098 if (app.renderThreadTid != 0) {
22099 setThreadScheduler(app.renderThreadTid,
22101 setThreadPriority(app.renderThreadTid, -4);
22103 } catch (IllegalArgumentException e) {
22105 "Failed to set scheduling policy, thread does not exist:\n"
22107 } catch (SecurityException e) {
22108 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22111 // Reset priority for top app UI and render threads
22112 setThreadPriority(app.pid, 0);
22113 if (app.renderThreadTid != 0) {
22114 setThreadPriority(app.renderThreadTid, 0);
22118 } catch (Exception e) {
22120 Slog.w(TAG, "Failed setting process group of " + app.pid
22121 + " to " + app.curSchedGroup);
22122 Slog.w(TAG, "at location", e);
22125 Binder.restoreCallingIdentity(oldId);
22129 if (app.repForegroundActivities != app.foregroundActivities) {
22130 app.repForegroundActivities = app.foregroundActivities;
22131 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22133 if (app.repProcState != app.curProcState) {
22134 app.repProcState = app.curProcState;
22135 if (app.thread != null) {
22138 //RuntimeException h = new RuntimeException("here");
22139 Slog.i(TAG, "Sending new process state " + app.repProcState
22140 + " to " + app /*, h*/);
22142 app.thread.setProcessState(app.repProcState);
22143 } catch (RemoteException e) {
22147 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22148 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22149 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22150 // Experimental code to more aggressively collect pss while
22151 // running test... the problem is that this tends to collect
22152 // the data right when a process is transitioning between process
22153 // states, which well tend to give noisy data.
22154 long start = SystemClock.uptimeMillis();
22155 long pss = Debug.getPss(app.pid, mTmpLong, null);
22156 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22157 mPendingPssProcesses.remove(app);
22158 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22159 + " to " + app.curProcState + ": "
22160 + (SystemClock.uptimeMillis()-start) + "ms");
22162 app.lastStateTime = now;
22163 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22164 mTestPssMode, isSleepingLocked(), now);
22165 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22166 + ProcessList.makeProcStateString(app.setProcState) + " to "
22167 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22168 + (app.nextPssTime-now) + ": " + app);
22170 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22171 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22173 requestPssLocked(app, app.setProcState);
22174 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22175 mTestPssMode, isSleepingLocked(), now);
22176 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22177 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22179 if (app.setProcState != app.curProcState) {
22180 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22181 String msg = "Proc state change of " + app.processName
22182 + " to " + app.curProcState;
22183 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22185 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22186 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22187 if (setImportant && !curImportant) {
22188 // This app is no longer something we consider important enough to allow to
22189 // use arbitrary amounts of battery power. Note
22190 // its current CPU time to later know to kill it if
22191 // it is not behaving well.
22192 app.whenUnimportant = now;
22193 app.lastCpuTime = 0;
22195 // Inform UsageStats of important process state change
22196 // Must be called before updating setProcState
22197 maybeUpdateUsageStatsLocked(app, nowElapsed);
22199 app.setProcState = app.curProcState;
22200 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22201 app.notCachedSinceIdle = false;
22204 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22206 app.procStateChanged = true;
22208 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22209 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22210 // For apps that sit around for a long time in the interactive state, we need
22211 // to report this at least once a day so they don't go idle.
22212 maybeUpdateUsageStatsLocked(app, nowElapsed);
22215 if (changes != 0) {
22216 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22217 "Changes in " + app + ": " + changes);
22218 int i = mPendingProcessChanges.size()-1;
22219 ProcessChangeItem item = null;
22221 item = mPendingProcessChanges.get(i);
22222 if (item.pid == app.pid) {
22223 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22224 "Re-using existing item: " + item);
22230 // No existing item in pending changes; need a new one.
22231 final int NA = mAvailProcessChanges.size();
22233 item = mAvailProcessChanges.remove(NA-1);
22234 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22235 "Retrieving available item: " + item);
22237 item = new ProcessChangeItem();
22238 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22239 "Allocating new item: " + item);
22242 item.pid = app.pid;
22243 item.uid = app.info.uid;
22244 if (mPendingProcessChanges.size() == 0) {
22245 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22246 "*** Enqueueing dispatch processes changed!");
22247 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22249 mPendingProcessChanges.add(item);
22251 item.changes |= changes;
22252 item.foregroundActivities = app.repForegroundActivities;
22253 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22254 "Item " + Integer.toHexString(System.identityHashCode(item))
22255 + " " + app.toShortString() + ": changes=" + item.changes
22256 + " foreground=" + item.foregroundActivities
22257 + " type=" + app.adjType + " source=" + app.adjSource
22258 + " target=" + app.adjTarget);
22264 private boolean isEphemeralLocked(int uid) {
22265 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22266 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22269 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22274 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22275 final UidRecord.ChangeItem pendingChange;
22276 if (uidRec == null || uidRec.pendingChange == null) {
22277 if (mPendingUidChanges.size() == 0) {
22278 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22279 "*** Enqueueing dispatch uid changed!");
22280 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22282 final int NA = mAvailUidChanges.size();
22284 pendingChange = mAvailUidChanges.remove(NA-1);
22285 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22286 "Retrieving available item: " + pendingChange);
22288 pendingChange = new UidRecord.ChangeItem();
22289 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22290 "Allocating new item: " + pendingChange);
22292 if (uidRec != null) {
22293 uidRec.pendingChange = pendingChange;
22294 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22295 // If this uid is going away, and we haven't yet reported it is gone,
22297 change |= UidRecord.CHANGE_IDLE;
22299 } else if (uid < 0) {
22300 throw new IllegalArgumentException("No UidRecord or uid");
22302 pendingChange.uidRecord = uidRec;
22303 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22304 mPendingUidChanges.add(pendingChange);
22306 pendingChange = uidRec.pendingChange;
22307 // If there is no change in idle or active state, then keep whatever was pending.
22308 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22309 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22310 | UidRecord.CHANGE_ACTIVE));
22312 // If there is no change in cached or uncached state, then keep whatever was pending.
22313 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22314 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22315 | UidRecord.CHANGE_UNCACHED));
22317 // If this is a report of the UID being gone, then we shouldn't keep any previous
22318 // report of it being active or cached. (That is, a gone uid is never active,
22319 // and never cached.)
22320 if ((change & UidRecord.CHANGE_GONE) != 0) {
22321 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22322 if (!uidRec.idle) {
22323 // If this uid is going away, and we haven't yet reported it is gone,
22325 change |= UidRecord.CHANGE_IDLE;
22329 pendingChange.change = change;
22330 pendingChange.processState = uidRec != null
22331 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22332 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22333 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22334 if (uidRec != null) {
22335 uidRec.lastReportedChange = change;
22336 uidRec.updateLastDispatchedProcStateSeq(change);
22339 // Directly update the power manager, since we sit on top of it and it is critical
22340 // it be kept in sync (so wake locks will be held as soon as appropriate).
22341 if (mLocalPowerManager != null) {
22342 // TO DO: dispatch cached/uncached changes here, so we don't need to report
22343 // all proc state changes.
22344 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22345 mLocalPowerManager.uidActive(pendingChange.uid);
22347 if ((change & UidRecord.CHANGE_IDLE) != 0) {
22348 mLocalPowerManager.uidIdle(pendingChange.uid);
22350 if ((change & UidRecord.CHANGE_GONE) != 0) {
22351 mLocalPowerManager.uidGone(pendingChange.uid);
22353 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22354 pendingChange.processState);
22359 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22360 String authority) {
22361 if (app == null) return;
22362 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22363 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22364 if (userState == null) return;
22365 final long now = SystemClock.elapsedRealtime();
22366 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22367 if (lastReported == null || lastReported < now - 60 * 1000L) {
22368 if (mSystemReady) {
22369 // Cannot touch the user stats if not system ready
22370 mUsageStatsService.reportContentProviderUsage(
22371 authority, providerPkgName, app.userId);
22373 userState.mProviderLastReportedFg.put(authority, now);
22378 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22379 if (DEBUG_USAGE_STATS) {
22380 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22381 + "] state changes: old = " + app.setProcState + ", new = "
22382 + app.curProcState);
22384 if (mUsageStatsService == null) {
22387 boolean isInteraction;
22388 // To avoid some abuse patterns, we are going to be careful about what we consider
22389 // to be an app interaction. Being the top activity doesn't count while the display
22390 // is sleeping, nor do short foreground services.
22391 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22392 isInteraction = true;
22393 app.fgInteractionTime = 0;
22394 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22395 if (app.fgInteractionTime == 0) {
22396 app.fgInteractionTime = nowElapsed;
22397 isInteraction = false;
22399 isInteraction = nowElapsed > app.fgInteractionTime
22400 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22403 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22404 app.fgInteractionTime = 0;
22406 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22407 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22408 app.interactionEventTime = nowElapsed;
22409 String[] packages = app.getPackageList();
22410 if (packages != null) {
22411 for (int i = 0; i < packages.length; i++) {
22412 mUsageStatsService.reportEvent(packages[i], app.userId,
22413 UsageEvents.Event.SYSTEM_INTERACTION);
22417 app.reportedInteraction = isInteraction;
22418 if (!isInteraction) {
22419 app.interactionEventTime = 0;
22423 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22424 if (proc.thread != null) {
22425 if (proc.baseProcessTracker != null) {
22426 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22431 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22432 ProcessRecord TOP_APP, boolean doingAll, long now) {
22433 if (app.thread == null) {
22437 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22439 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22442 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22444 if (isForeground != proc.foregroundServices) {
22445 proc.foregroundServices = isForeground;
22446 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22448 if (isForeground) {
22449 if (curProcs == null) {
22450 curProcs = new ArrayList<ProcessRecord>();
22451 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22453 if (!curProcs.contains(proc)) {
22454 curProcs.add(proc);
22455 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22456 proc.info.packageName, proc.info.uid);
22459 if (curProcs != null) {
22460 if (curProcs.remove(proc)) {
22461 mBatteryStatsService.noteEvent(
22462 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22463 proc.info.packageName, proc.info.uid);
22464 if (curProcs.size() <= 0) {
22465 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22471 updateOomAdjLocked();
22476 private final ActivityRecord resumedAppLocked() {
22477 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22481 pkg = act.packageName;
22482 uid = act.info.applicationInfo.uid;
22487 // Has the UID or resumed package name changed?
22488 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22489 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22490 if (mCurResumedPackage != null) {
22491 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22492 mCurResumedPackage, mCurResumedUid);
22494 mCurResumedPackage = pkg;
22495 mCurResumedUid = uid;
22496 if (mCurResumedPackage != null) {
22497 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22498 mCurResumedPackage, mCurResumedUid);
22505 * Update OomAdj for a specific process.
22506 * @param app The process to update
22507 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22508 * if necessary, or skip.
22509 * @return whether updateOomAdjLocked(app) was successful.
22511 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22512 final ActivityRecord TOP_ACT = resumedAppLocked();
22513 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22514 final boolean wasCached = app.cached;
22518 // This is the desired cached adjusment we want to tell it to use.
22519 // If our app is currently cached, we know it, and that is it. Otherwise,
22520 // we don't know it yet, and it needs to now be cached we will then
22521 // need to do a complete oom adj.
22522 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22523 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22524 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22525 SystemClock.uptimeMillis());
22527 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22528 // Changed to/from cached state, so apps after it in the LRU
22529 // list may also be changed.
22530 updateOomAdjLocked();
22535 final void updateOomAdjLocked() {
22536 final ActivityRecord TOP_ACT = resumedAppLocked();
22537 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22538 final long now = SystemClock.uptimeMillis();
22539 final long nowElapsed = SystemClock.elapsedRealtime();
22540 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22541 final int N = mLruProcesses.size();
22544 RuntimeException e = new RuntimeException();
22545 e.fillInStackTrace();
22546 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22549 // Reset state in all uid records.
22550 for (int i=mActiveUids.size()-1; i>=0; i--) {
22551 final UidRecord uidRec = mActiveUids.valueAt(i);
22552 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22553 "Starting update of " + uidRec);
22557 mStackSupervisor.rankTaskLayersIfNeeded();
22560 mNewNumServiceProcs = 0;
22561 mNewNumAServiceProcs = 0;
22563 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22564 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22566 // Let's determine how many processes we have running vs.
22567 // how many slots we have for background processes; we may want
22568 // to put multiple processes in a slot of there are enough of
22570 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22571 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22572 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22573 if (numEmptyProcs > cachedProcessLimit) {
22574 // If there are more empty processes than our limit on cached
22575 // processes, then use the cached process limit for the factor.
22576 // This ensures that the really old empty processes get pushed
22577 // down to the bottom, so if we are running low on memory we will
22578 // have a better chance at keeping around more cached processes
22579 // instead of a gazillion empty processes.
22580 numEmptyProcs = cachedProcessLimit;
22582 int emptyFactor = numEmptyProcs/numSlots;
22583 if (emptyFactor < 1) emptyFactor = 1;
22584 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22585 if (cachedFactor < 1) cachedFactor = 1;
22586 int stepCached = 0;
22590 int numTrimming = 0;
22592 mNumNonCachedProcs = 0;
22593 mNumCachedHiddenProcs = 0;
22595 // First update the OOM adjustment for each of the
22596 // application processes based on their current state.
22597 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22598 int nextCachedAdj = curCachedAdj+1;
22599 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22600 int nextEmptyAdj = curEmptyAdj+2;
22601 for (int i=N-1; i>=0; i--) {
22602 ProcessRecord app = mLruProcesses.get(i);
22603 if (!app.killedByAm && app.thread != null) {
22604 app.procStateChanged = false;
22605 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22607 // If we haven't yet assigned the final cached adj
22608 // to the process, do that now.
22609 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22610 switch (app.curProcState) {
22611 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22612 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22613 // This process is a cached process holding activities...
22614 // assign it the next cached value for that type, and then
22615 // step that cached level.
22616 app.curRawAdj = curCachedAdj;
22617 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22618 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22619 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22621 if (curCachedAdj != nextCachedAdj) {
22623 if (stepCached >= cachedFactor) {
22625 curCachedAdj = nextCachedAdj;
22626 nextCachedAdj += 2;
22627 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22628 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22634 // For everything else, assign next empty cached process
22635 // level and bump that up. Note that this means that
22636 // long-running services that have dropped down to the
22637 // cached level will be treated as empty (since their process
22638 // state is still as a service), which is what we want.
22639 app.curRawAdj = curEmptyAdj;
22640 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22641 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22642 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22644 if (curEmptyAdj != nextEmptyAdj) {
22646 if (stepEmpty >= emptyFactor) {
22648 curEmptyAdj = nextEmptyAdj;
22650 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22651 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22659 applyOomAdjLocked(app, true, now, nowElapsed);
22661 // Count the number of process types.
22662 switch (app.curProcState) {
22663 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22664 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22665 mNumCachedHiddenProcs++;
22667 if (numCached > cachedProcessLimit) {
22668 app.kill("cached #" + numCached, true);
22671 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22672 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22673 && app.lastActivityTime < oldTime) {
22674 app.kill("empty for "
22675 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22676 / 1000) + "s", true);
22679 if (numEmpty > emptyProcessLimit) {
22680 app.kill("empty #" + numEmpty, true);
22685 mNumNonCachedProcs++;
22689 if (app.isolated && app.services.size() <= 0) {
22690 // If this is an isolated process, and there are no
22691 // services running in it, then the process is no longer
22692 // needed. We agressively kill these because we can by
22693 // definition not re-use the same process again, and it is
22694 // good to avoid having whatever code was running in them
22695 // left sitting around after no longer needed.
22696 app.kill("isolated not needed", true);
22698 // Keeping this process, update its uid.
22699 final UidRecord uidRec = app.uidRecord;
22700 if (uidRec != null) {
22701 uidRec.ephemeral = app.info.isInstantApp();
22702 if (uidRec.curProcState > app.curProcState) {
22703 uidRec.curProcState = app.curProcState;
22705 if (app.foregroundServices) {
22706 uidRec.foregroundServices = true;
22711 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22712 && !app.killedByAm) {
22718 incrementProcStateSeqAndNotifyAppsLocked();
22720 mNumServiceProcs = mNewNumServiceProcs;
22722 // Now determine the memory trimming level of background processes.
22723 // Unfortunately we need to start at the back of the list to do this
22724 // properly. We only do this if the number of background apps we
22725 // are managing to keep around is less than half the maximum we desire;
22726 // if we are keeping a good number around, we'll let them use whatever
22727 // memory they want.
22728 final int numCachedAndEmpty = numCached + numEmpty;
22730 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22731 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22732 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22733 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22734 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22735 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22737 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22740 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22742 // We always allow the memory level to go up (better). We only allow it to go
22743 // down if we are in a state where that is allowed, *and* the total number of processes
22744 // has gone down since last time.
22745 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22746 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22747 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22748 if (memFactor > mLastMemoryLevel) {
22749 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22750 memFactor = mLastMemoryLevel;
22751 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22754 if (memFactor != mLastMemoryLevel) {
22755 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22757 mLastMemoryLevel = memFactor;
22758 mLastNumProcesses = mLruProcesses.size();
22759 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22760 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22761 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22762 if (mLowRamStartTime == 0) {
22763 mLowRamStartTime = now;
22767 switch (memFactor) {
22768 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22769 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22771 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22772 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22775 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22778 int factor = numTrimming/3;
22780 if (mHomeProcess != null) minFactor++;
22781 if (mPreviousProcess != null) minFactor++;
22782 if (factor < minFactor) factor = minFactor;
22783 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22784 for (int i=N-1; i>=0; i--) {
22785 ProcessRecord app = mLruProcesses.get(i);
22786 if (allChanged || app.procStateChanged) {
22787 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22788 app.procStateChanged = false;
22790 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22791 && !app.killedByAm) {
22792 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22794 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22795 "Trimming memory of " + app.processName + " to " + curLevel);
22796 app.thread.scheduleTrimMemory(curLevel);
22797 } catch (RemoteException e) {
22800 // For now we won't do this; our memory trimming seems
22801 // to be good enough at this point that destroying
22802 // activities causes more harm than good.
22803 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22804 && app != mHomeProcess && app != mPreviousProcess) {
22805 // Need to do this on its own message because the stack may not
22806 // be in a consistent state at this point.
22807 // For these apps we will also finish their activities
22808 // to help them free memory.
22809 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22813 app.trimMemoryLevel = curLevel;
22815 if (step >= factor) {
22817 switch (curLevel) {
22818 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22819 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22821 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22822 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22826 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22827 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22828 && app.thread != null) {
22830 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22831 "Trimming memory of heavy-weight " + app.processName
22832 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22833 app.thread.scheduleTrimMemory(
22834 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22835 } catch (RemoteException e) {
22838 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22840 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22841 || app.systemNoUi) && app.pendingUiClean) {
22842 // If this application is now in the background and it
22843 // had done UI, then give it the special trim level to
22844 // have it free UI resources.
22845 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22846 if (app.trimMemoryLevel < level && app.thread != null) {
22848 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22849 "Trimming memory of bg-ui " + app.processName
22851 app.thread.scheduleTrimMemory(level);
22852 } catch (RemoteException e) {
22855 app.pendingUiClean = false;
22857 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22859 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22860 "Trimming memory of fg " + app.processName
22861 + " to " + fgTrimLevel);
22862 app.thread.scheduleTrimMemory(fgTrimLevel);
22863 } catch (RemoteException e) {
22866 app.trimMemoryLevel = fgTrimLevel;
22870 if (mLowRamStartTime != 0) {
22871 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22872 mLowRamStartTime = 0;
22874 for (int i=N-1; i>=0; i--) {
22875 ProcessRecord app = mLruProcesses.get(i);
22876 if (allChanged || app.procStateChanged) {
22877 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22878 app.procStateChanged = false;
22880 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22881 || app.systemNoUi) && app.pendingUiClean) {
22882 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22883 && app.thread != null) {
22885 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22886 "Trimming memory of ui hidden " + app.processName
22887 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22888 app.thread.scheduleTrimMemory(
22889 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22890 } catch (RemoteException e) {
22893 app.pendingUiClean = false;
22895 app.trimMemoryLevel = 0;
22899 if (mAlwaysFinishActivities) {
22900 // Need to do this on its own message because the stack may not
22901 // be in a consistent state at this point.
22902 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22906 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22909 ArrayList<UidRecord> becameIdle = null;
22911 // Update from any uid changes.
22912 if (mLocalPowerManager != null) {
22913 mLocalPowerManager.startUidChanges();
22915 for (int i=mActiveUids.size()-1; i>=0; i--) {
22916 final UidRecord uidRec = mActiveUids.valueAt(i);
22917 int uidChange = UidRecord.CHANGE_PROCSTATE;
22918 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22919 && (uidRec.setProcState != uidRec.curProcState
22920 || uidRec.setWhitelist != uidRec.curWhitelist)) {
22921 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22922 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22923 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22924 + " to " + uidRec.curWhitelist);
22925 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22926 && !uidRec.curWhitelist) {
22927 // UID is now in the background (and not on the temp whitelist). Was it
22928 // previously in the foreground (or on the temp whitelist)?
22929 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22930 || uidRec.setWhitelist) {
22931 uidRec.lastBackgroundTime = nowElapsed;
22932 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22933 // Note: the background settle time is in elapsed realtime, while
22934 // the handler time base is uptime. All this means is that we may
22935 // stop background uids later than we had intended, but that only
22936 // happens because the device was sleeping so we are okay anyway.
22937 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22938 mConstants.BACKGROUND_SETTLE_TIME);
22941 if (uidRec.idle && !uidRec.setIdle) {
22942 uidChange = UidRecord.CHANGE_IDLE;
22943 if (becameIdle == null) {
22944 becameIdle = new ArrayList<>();
22946 becameIdle.add(uidRec);
22950 uidChange = UidRecord.CHANGE_ACTIVE;
22951 EventLogTags.writeAmUidActive(uidRec.uid);
22952 uidRec.idle = false;
22954 uidRec.lastBackgroundTime = 0;
22956 final boolean wasCached = uidRec.setProcState
22957 > ActivityManager.PROCESS_STATE_RECEIVER;
22958 final boolean isCached = uidRec.curProcState
22959 > ActivityManager.PROCESS_STATE_RECEIVER;
22960 if (wasCached != isCached ||
22961 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22962 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22964 uidRec.setProcState = uidRec.curProcState;
22965 uidRec.setWhitelist = uidRec.curWhitelist;
22966 uidRec.setIdle = uidRec.idle;
22967 enqueueUidChangeLocked(uidRec, -1, uidChange);
22968 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22969 if (uidRec.foregroundServices) {
22970 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22974 if (mLocalPowerManager != null) {
22975 mLocalPowerManager.finishUidChanges();
22978 if (becameIdle != null) {
22979 // If we have any new uids that became idle this time, we need to make sure
22980 // they aren't left with running services.
22981 for (int i = becameIdle.size() - 1; i >= 0; i--) {
22982 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22986 if (mProcessStats.shouldWriteNowLocked(now)) {
22987 mHandler.post(new Runnable() {
22988 @Override public void run() {
22989 synchronized (ActivityManagerService.this) {
22990 mProcessStats.writeStateAsyncLocked();
22996 if (DEBUG_OOM_ADJ) {
22997 final long duration = SystemClock.uptimeMillis() - now;
22999 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23000 new RuntimeException("here").fillInStackTrace());
23002 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23008 public void makePackageIdle(String packageName, int userId) {
23009 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23010 != PackageManager.PERMISSION_GRANTED) {
23011 String msg = "Permission Denial: makePackageIdle() from pid="
23012 + Binder.getCallingPid()
23013 + ", uid=" + Binder.getCallingUid()
23014 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23016 throw new SecurityException(msg);
23018 final int callingPid = Binder.getCallingPid();
23019 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23020 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23021 long callingId = Binder.clearCallingIdentity();
23022 synchronized(this) {
23024 IPackageManager pm = AppGlobals.getPackageManager();
23027 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23028 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23029 } catch (RemoteException e) {
23031 if (pkgUid == -1) {
23032 throw new IllegalArgumentException("Unknown package name " + packageName);
23035 if (mLocalPowerManager != null) {
23036 mLocalPowerManager.startUidChanges();
23038 final int appId = UserHandle.getAppId(pkgUid);
23039 final int N = mActiveUids.size();
23040 for (int i=N-1; i>=0; i--) {
23041 final UidRecord uidRec = mActiveUids.valueAt(i);
23042 final long bgTime = uidRec.lastBackgroundTime;
23043 if (bgTime > 0 && !uidRec.idle) {
23044 if (UserHandle.getAppId(uidRec.uid) == appId) {
23045 if (userId == UserHandle.USER_ALL ||
23046 userId == UserHandle.getUserId(uidRec.uid)) {
23047 EventLogTags.writeAmUidIdle(uidRec.uid);
23048 uidRec.idle = true;
23049 uidRec.setIdle = true;
23050 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23051 + " from package " + packageName + " user " + userId);
23052 doStopUidLocked(uidRec.uid, uidRec);
23058 if (mLocalPowerManager != null) {
23059 mLocalPowerManager.finishUidChanges();
23061 Binder.restoreCallingIdentity(callingId);
23066 final void idleUids() {
23067 synchronized (this) {
23068 final int N = mActiveUids.size();
23072 final long nowElapsed = SystemClock.elapsedRealtime();
23073 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23075 if (mLocalPowerManager != null) {
23076 mLocalPowerManager.startUidChanges();
23078 for (int i=N-1; i>=0; i--) {
23079 final UidRecord uidRec = mActiveUids.valueAt(i);
23080 final long bgTime = uidRec.lastBackgroundTime;
23081 if (bgTime > 0 && !uidRec.idle) {
23082 if (bgTime <= maxBgTime) {
23083 EventLogTags.writeAmUidIdle(uidRec.uid);
23084 uidRec.idle = true;
23085 uidRec.setIdle = true;
23086 doStopUidLocked(uidRec.uid, uidRec);
23088 if (nextTime == 0 || nextTime > bgTime) {
23094 if (mLocalPowerManager != null) {
23095 mLocalPowerManager.finishUidChanges();
23097 if (nextTime > 0) {
23098 mHandler.removeMessages(IDLE_UIDS_MSG);
23099 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23100 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23106 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23107 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23108 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23112 void incrementProcStateSeqAndNotifyAppsLocked() {
23113 if (mWaitForNetworkTimeoutMs <= 0) {
23116 // Used for identifying which uids need to block for network.
23117 ArrayList<Integer> blockingUids = null;
23118 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23119 final UidRecord uidRec = mActiveUids.valueAt(i);
23120 // If the network is not restricted for uid, then nothing to do here.
23121 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23124 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23127 // If process state is not changed, then there's nothing to do.
23128 if (uidRec.setProcState == uidRec.curProcState) {
23131 final int blockState = getBlockStateForUid(uidRec);
23132 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23133 // there's nothing the app needs to do in this scenario.
23134 if (blockState == NETWORK_STATE_NO_CHANGE) {
23137 synchronized (uidRec.networkStateLock) {
23138 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23139 if (blockState == NETWORK_STATE_BLOCK) {
23140 if (blockingUids == null) {
23141 blockingUids = new ArrayList<>();
23143 blockingUids.add(uidRec.uid);
23145 if (DEBUG_NETWORK) {
23146 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23147 + " threads for uid: " + uidRec);
23149 if (uidRec.waitingForNetwork) {
23150 uidRec.networkStateLock.notifyAll();
23156 // There are no uids that need to block, so nothing more to do.
23157 if (blockingUids == null) {
23161 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23162 final ProcessRecord app = mLruProcesses.get(i);
23163 if (!blockingUids.contains(app.uid)) {
23166 if (!app.killedByAm && app.thread != null) {
23167 final UidRecord uidRec = mActiveUids.get(app.uid);
23169 if (DEBUG_NETWORK) {
23170 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23173 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23174 } catch (RemoteException ignored) {
23181 * Checks if the uid is coming from background to foreground or vice versa and returns
23182 * appropriate block state based on this.
23184 * @return blockState based on whether the uid is coming from background to foreground or
23185 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23186 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23187 * {@link #NETWORK_STATE_NO_CHANGE}.
23190 int getBlockStateForUid(UidRecord uidRec) {
23191 // Denotes whether uid's process state is currently allowed network access.
23192 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23193 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23194 // Denotes whether uid's process state was previously allowed network access.
23195 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23196 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23198 // When the uid is coming to foreground, AMS should inform the app thread that it should
23199 // block for the network rules to get updated before launching an activity.
23200 if (!wasAllowed && isAllowed) {
23201 return NETWORK_STATE_BLOCK;
23203 // When the uid is going to background, AMS should inform the app thread that if an
23204 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23205 if (wasAllowed && !isAllowed) {
23206 return NETWORK_STATE_UNBLOCK;
23208 return NETWORK_STATE_NO_CHANGE;
23211 final void runInBackgroundDisabled(int uid) {
23212 synchronized (this) {
23213 UidRecord uidRec = mActiveUids.get(uid);
23214 if (uidRec != null) {
23215 // This uid is actually running... should it be considered background now?
23217 doStopUidLocked(uidRec.uid, uidRec);
23220 // This uid isn't actually running... still send a report about it being "stopped".
23221 doStopUidLocked(uid, null);
23226 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23227 mServices.stopInBackgroundLocked(uid);
23228 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23232 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23234 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23235 long duration, String tag) {
23236 if (DEBUG_WHITELISTS) {
23237 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23238 + targetUid + ", " + duration + ")");
23241 synchronized (mPidsSelfLocked) {
23242 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23244 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23248 if (!pr.whitelistManager) {
23249 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23250 != PackageManager.PERMISSION_GRANTED) {
23251 if (DEBUG_WHITELISTS) {
23252 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23253 + ": pid " + callerPid + " is not allowed");
23260 tempWhitelistUidLocked(targetUid, duration, tag);
23264 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23266 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23267 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23268 setUidTempWhitelistStateLocked(targetUid, true);
23269 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23272 void pushTempWhitelist() {
23274 final PendingTempWhitelist[] list;
23276 // First copy out the pending changes... we need to leave them in the map for now,
23277 // in case someone needs to check what is coming up while we don't have the lock held.
23278 synchronized(this) {
23279 N = mPendingTempWhitelist.size();
23280 list = new PendingTempWhitelist[N];
23281 for (int i = 0; i < N; i++) {
23282 list[i] = mPendingTempWhitelist.valueAt(i);
23286 // Now safely dispatch changes to device idle controller.
23287 for (int i = 0; i < N; i++) {
23288 PendingTempWhitelist ptw = list[i];
23289 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23290 ptw.duration, true, ptw.tag);
23293 // And now we can safely remove them from the map.
23294 synchronized(this) {
23295 for (int i = 0; i < N; i++) {
23296 PendingTempWhitelist ptw = list[i];
23297 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23298 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23299 mPendingTempWhitelist.removeAt(index);
23305 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23306 boolean changed = false;
23307 for (int i=mActiveUids.size()-1; i>=0; i--) {
23308 final UidRecord uidRec = mActiveUids.valueAt(i);
23309 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23310 uidRec.curWhitelist = onWhitelist;
23315 updateOomAdjLocked();
23319 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23320 boolean changed = false;
23321 final UidRecord uidRec = mActiveUids.get(uid);
23322 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23323 uidRec.curWhitelist = onWhitelist;
23324 updateOomAdjLocked();
23328 final void trimApplications() {
23329 synchronized (this) {
23332 // First remove any unused application processes whose package
23333 // has been removed.
23334 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23335 final ProcessRecord app = mRemovedProcesses.get(i);
23336 if (app.activities.size() == 0
23337 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23339 TAG, "Exiting empty application process "
23340 + app.toShortString() + " ("
23341 + (app.thread != null ? app.thread.asBinder() : null)
23343 if (app.pid > 0 && app.pid != MY_PID) {
23344 app.kill("empty", false);
23347 app.thread.scheduleExit();
23348 } catch (Exception e) {
23349 // Ignore exceptions.
23352 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23353 mRemovedProcesses.remove(i);
23355 if (app.persistent) {
23356 addAppLocked(app.info, null, false, null /* ABI override */);
23361 // Now update the oom adj for all processes.
23362 updateOomAdjLocked();
23366 /** This method sends the specified signal to each of the persistent apps */
23367 public void signalPersistentProcesses(int sig) throws RemoteException {
23368 if (sig != SIGNAL_USR1) {
23369 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23372 synchronized (this) {
23373 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23374 != PackageManager.PERMISSION_GRANTED) {
23375 throw new SecurityException("Requires permission "
23376 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23379 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23380 ProcessRecord r = mLruProcesses.get(i);
23381 if (r.thread != null && r.persistent) {
23382 sendSignal(r.pid, sig);
23388 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23389 if (proc == null || proc == mProfileProc) {
23390 proc = mProfileProc;
23391 profileType = mProfileType;
23392 clearProfilerLocked();
23394 if (proc == null) {
23398 proc.thread.profilerControl(false, null, profileType);
23399 } catch (RemoteException e) {
23400 throw new IllegalStateException("Process disappeared");
23404 private void clearProfilerLocked() {
23405 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23407 mProfilerInfo.profileFd.close();
23408 } catch (IOException e) {
23411 mProfileApp = null;
23412 mProfileProc = null;
23413 mProfilerInfo = null;
23416 public boolean profileControl(String process, int userId, boolean start,
23417 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23420 synchronized (this) {
23421 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23422 // its own permission.
23423 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23424 != PackageManager.PERMISSION_GRANTED) {
23425 throw new SecurityException("Requires permission "
23426 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23429 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23430 throw new IllegalArgumentException("null profile info or fd");
23433 ProcessRecord proc = null;
23434 if (process != null) {
23435 proc = findProcessLocked(process, userId, "profileControl");
23438 if (start && (proc == null || proc.thread == null)) {
23439 throw new IllegalArgumentException("Unknown process: " + process);
23443 stopProfilerLocked(null, 0);
23444 setProfileApp(proc.info, proc.processName, profilerInfo);
23445 mProfileProc = proc;
23446 mProfileType = profileType;
23447 ParcelFileDescriptor fd = profilerInfo.profileFd;
23450 } catch (IOException e) {
23453 profilerInfo.profileFd = fd;
23454 proc.thread.profilerControl(start, profilerInfo, profileType);
23457 mProfilerInfo.profileFd.close();
23458 } catch (IOException e) {
23460 mProfilerInfo.profileFd = null;
23462 stopProfilerLocked(proc, profileType);
23463 if (profilerInfo != null && profilerInfo.profileFd != null) {
23465 profilerInfo.profileFd.close();
23466 } catch (IOException e) {
23473 } catch (RemoteException e) {
23474 throw new IllegalStateException("Process disappeared");
23476 if (profilerInfo != null && profilerInfo.profileFd != null) {
23478 profilerInfo.profileFd.close();
23479 } catch (IOException e) {
23485 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23486 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23487 userId, true, ALLOW_FULL_ONLY, callName, null);
23488 ProcessRecord proc = null;
23490 int pid = Integer.parseInt(process);
23491 synchronized (mPidsSelfLocked) {
23492 proc = mPidsSelfLocked.get(pid);
23494 } catch (NumberFormatException e) {
23497 if (proc == null) {
23498 ArrayMap<String, SparseArray<ProcessRecord>> all
23499 = mProcessNames.getMap();
23500 SparseArray<ProcessRecord> procs = all.get(process);
23501 if (procs != null && procs.size() > 0) {
23502 proc = procs.valueAt(0);
23503 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23504 for (int i=1; i<procs.size(); i++) {
23505 ProcessRecord thisProc = procs.valueAt(i);
23506 if (thisProc.userId == userId) {
23518 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23519 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23522 synchronized (this) {
23523 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23524 // its own permission (same as profileControl).
23525 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23526 != PackageManager.PERMISSION_GRANTED) {
23527 throw new SecurityException("Requires permission "
23528 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23532 throw new IllegalArgumentException("null fd");
23535 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23536 if (proc == null || proc.thread == null) {
23537 throw new IllegalArgumentException("Unknown process: " + process);
23540 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23541 if (!isDebuggable) {
23542 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23543 throw new SecurityException("Process not debuggable: " + proc);
23547 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23551 } catch (RemoteException e) {
23552 throw new IllegalStateException("Process disappeared");
23557 } catch (IOException e) {
23564 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23565 String reportPackage) {
23566 if (processName != null) {
23567 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23568 "setDumpHeapDebugLimit()");
23570 synchronized (mPidsSelfLocked) {
23571 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23572 if (proc == null) {
23573 throw new SecurityException("No process found for calling pid "
23574 + Binder.getCallingPid());
23576 if (!Build.IS_DEBUGGABLE
23577 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23578 throw new SecurityException("Not running a debuggable build");
23580 processName = proc.processName;
23582 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23583 throw new SecurityException("Package " + reportPackage + " is not running in "
23588 synchronized (this) {
23589 if (maxMemSize > 0) {
23590 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23593 mMemWatchProcesses.remove(processName, uid);
23595 mMemWatchProcesses.getMap().remove(processName);
23602 public void dumpHeapFinished(String path) {
23603 synchronized (this) {
23604 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23605 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23606 + " does not match last pid " + mMemWatchDumpPid);
23609 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23610 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23611 + " does not match last path " + mMemWatchDumpFile);
23614 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23615 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23617 // Forced gc to clean up the remnant hprof fd.
23618 Runtime.getRuntime().gc();
23622 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23623 public void monitor() {
23624 synchronized (this) { }
23627 void onCoreSettingsChange(Bundle settings) {
23628 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23629 ProcessRecord processRecord = mLruProcesses.get(i);
23631 if (processRecord.thread != null) {
23632 processRecord.thread.setCoreSettings(settings);
23634 } catch (RemoteException re) {
23640 // Multi-user methods
23643 * Start user, if its not already running, but don't bring it to foreground.
23646 public boolean startUserInBackground(final int userId) {
23647 return mUserController.startUser(userId, /* foreground */ false);
23651 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23652 return mUserController.unlockUser(userId, token, secret, listener);
23656 public boolean switchUser(final int targetUserId) {
23657 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23659 UserInfo targetUserInfo;
23660 synchronized (this) {
23661 currentUserId = mUserController.getCurrentUserIdLocked();
23662 targetUserInfo = mUserController.getUserInfo(targetUserId);
23663 if (targetUserId == currentUserId) {
23664 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23667 if (targetUserInfo == null) {
23668 Slog.w(TAG, "No user info for user #" + targetUserId);
23671 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23672 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23673 + " when device is in demo mode");
23676 if (!targetUserInfo.supportsSwitchTo()) {
23677 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23680 if (targetUserInfo.isManagedProfile()) {
23681 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23684 mUserController.setTargetUserIdLocked(targetUserId);
23686 if (mUserController.mUserSwitchUiEnabled) {
23687 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23688 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23689 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23690 mUiHandler.sendMessage(mHandler.obtainMessage(
23691 START_USER_SWITCH_UI_MSG, userNames));
23693 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23694 mHandler.sendMessage(mHandler.obtainMessage(
23695 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23700 void scheduleStartProfilesLocked() {
23701 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23702 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23703 DateUtils.SECOND_IN_MILLIS);
23708 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23709 return mUserController.stopUser(userId, force, callback);
23713 public UserInfo getCurrentUser() {
23714 return mUserController.getCurrentUser();
23717 String getStartedUserState(int userId) {
23718 synchronized (this) {
23719 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23720 return UserState.stateToString(userState.state);
23725 public boolean isUserRunning(int userId, int flags) {
23726 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23727 && checkCallingPermission(INTERACT_ACROSS_USERS)
23728 != PackageManager.PERMISSION_GRANTED) {
23729 String msg = "Permission Denial: isUserRunning() from pid="
23730 + Binder.getCallingPid()
23731 + ", uid=" + Binder.getCallingUid()
23732 + " requires " + INTERACT_ACROSS_USERS;
23734 throw new SecurityException(msg);
23736 synchronized (this) {
23737 return mUserController.isUserRunningLocked(userId, flags);
23742 public int[] getRunningUserIds() {
23743 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23744 != PackageManager.PERMISSION_GRANTED) {
23745 String msg = "Permission Denial: isUserRunning() from pid="
23746 + Binder.getCallingPid()
23747 + ", uid=" + Binder.getCallingUid()
23748 + " requires " + INTERACT_ACROSS_USERS;
23750 throw new SecurityException(msg);
23752 synchronized (this) {
23753 return mUserController.getStartedUserArrayLocked();
23758 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23759 mUserController.registerUserSwitchObserver(observer, name);
23763 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23764 mUserController.unregisterUserSwitchObserver(observer);
23767 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23768 if (info == null) return null;
23769 ApplicationInfo newInfo = new ApplicationInfo(info);
23770 newInfo.initForUser(userId);
23774 public boolean isUserStopped(int userId) {
23775 synchronized (this) {
23776 return mUserController.getStartedUserStateLocked(userId) == null;
23780 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23782 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23786 ActivityInfo info = new ActivityInfo(aInfo);
23787 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23791 private boolean processSanityChecksLocked(ProcessRecord process) {
23792 if (process == null || process.thread == null) {
23796 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23797 if (!isDebuggable) {
23798 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23806 public boolean startBinderTracking() throws RemoteException {
23807 synchronized (this) {
23808 mBinderTransactionTrackingEnabled = true;
23809 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23810 // permission (same as profileControl).
23811 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23812 != PackageManager.PERMISSION_GRANTED) {
23813 throw new SecurityException("Requires permission "
23814 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23817 for (int i = 0; i < mLruProcesses.size(); i++) {
23818 ProcessRecord process = mLruProcesses.get(i);
23819 if (!processSanityChecksLocked(process)) {
23823 process.thread.startBinderTracking();
23824 } catch (RemoteException e) {
23825 Log.v(TAG, "Process disappared");
23832 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23834 synchronized (this) {
23835 mBinderTransactionTrackingEnabled = false;
23836 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23837 // permission (same as profileControl).
23838 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23839 != PackageManager.PERMISSION_GRANTED) {
23840 throw new SecurityException("Requires permission "
23841 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23845 throw new IllegalArgumentException("null fd");
23848 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23849 pw.println("Binder transaction traces for all processes.\n");
23850 for (ProcessRecord process : mLruProcesses) {
23851 if (!processSanityChecksLocked(process)) {
23855 pw.println("Traces for process: " + process.processName);
23858 TransferPipe tp = new TransferPipe();
23860 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23861 tp.go(fd.getFileDescriptor());
23865 } catch (IOException e) {
23866 pw.println("Failure while dumping IPC traces from " + process +
23867 ". Exception: " + e);
23869 } catch (RemoteException e) {
23870 pw.println("Got a RemoteException while dumping IPC traces from " +
23871 process + ". Exception: " + e);
23882 } catch (IOException e) {
23889 final class LocalService extends ActivityManagerInternal {
23891 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23892 int targetUserId) {
23893 synchronized (ActivityManagerService.this) {
23894 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23895 targetPkg, intent, null, targetUserId);
23900 public String checkContentProviderAccess(String authority, int userId) {
23901 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23905 public void onWakefulnessChanged(int wakefulness) {
23906 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23910 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23911 String processName, String abiOverride, int uid, Runnable crashHandler) {
23912 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23913 processName, abiOverride, uid, crashHandler);
23917 public SleepToken acquireSleepToken(String tag, int displayId) {
23918 Preconditions.checkNotNull(tag);
23919 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23923 public ComponentName getHomeActivityForUser(int userId) {
23924 synchronized (ActivityManagerService.this) {
23925 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23926 return homeActivity == null ? null : homeActivity.realActivity;
23931 public void onUserRemoved(int userId) {
23932 synchronized (ActivityManagerService.this) {
23933 ActivityManagerService.this.onUserStoppedLocked(userId);
23935 mBatteryStatsService.onUserRemoved(userId);
23939 public void onLocalVoiceInteractionStarted(IBinder activity,
23940 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23941 synchronized (ActivityManagerService.this) {
23942 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23943 voiceSession, voiceInteractor);
23948 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23949 synchronized (ActivityManagerService.this) {
23950 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23951 reasons, timestamp);
23956 public void notifyAppTransitionFinished() {
23957 synchronized (ActivityManagerService.this) {
23958 mStackSupervisor.notifyAppTransitionDone();
23963 public void notifyAppTransitionCancelled() {
23964 synchronized (ActivityManagerService.this) {
23965 mStackSupervisor.notifyAppTransitionDone();
23970 public List<IBinder> getTopVisibleActivities() {
23971 synchronized (ActivityManagerService.this) {
23972 return mStackSupervisor.getTopVisibleActivities();
23977 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23978 synchronized (ActivityManagerService.this) {
23979 mStackSupervisor.setDockedStackMinimized(minimized);
23984 public void killForegroundAppsForUser(int userHandle) {
23985 synchronized (ActivityManagerService.this) {
23986 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23987 final int NP = mProcessNames.getMap().size();
23988 for (int ip = 0; ip < NP; ip++) {
23989 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23990 final int NA = apps.size();
23991 for (int ia = 0; ia < NA; ia++) {
23992 final ProcessRecord app = apps.valueAt(ia);
23993 if (app.persistent) {
23994 // We don't kill persistent processes.
23999 } else if (app.userId == userHandle && app.foregroundActivities) {
24000 app.removed = true;
24006 final int N = procs.size();
24007 for (int i = 0; i < N; i++) {
24008 removeProcessLocked(procs.get(i), false, true, "kill all fg");
24014 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24016 if (!(target instanceof PendingIntentRecord)) {
24017 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24020 synchronized (ActivityManagerService.this) {
24021 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24026 public void setDeviceIdleWhitelist(int[] appids) {
24027 synchronized (ActivityManagerService.this) {
24028 mDeviceIdleWhitelist = appids;
24033 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24034 synchronized (ActivityManagerService.this) {
24035 mDeviceIdleTempWhitelist = appids;
24036 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24041 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24043 Preconditions.checkNotNull(values, "Configuration must not be null");
24044 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24045 synchronized (ActivityManagerService.this) {
24046 updateConfigurationLocked(values, null, false, true, userId,
24047 false /* deferResume */);
24052 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24054 Preconditions.checkNotNull(intents, "intents");
24055 final String[] resolvedTypes = new String[intents.length];
24056 for (int i = 0; i < intents.length; i++) {
24057 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24060 // UID of the package on user userId.
24061 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24062 // packageUid may not be initialized.
24063 int packageUid = 0;
24065 packageUid = AppGlobals.getPackageManager().getPackageUid(
24066 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24067 } catch (RemoteException e) {
24068 // Shouldn't happen.
24071 synchronized (ActivityManagerService.this) {
24072 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24073 /*resultTo*/ null, bOptions, userId);
24078 public int getUidProcessState(int uid) {
24079 return getUidState(uid);
24083 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24084 synchronized (ActivityManagerService.this) {
24086 // We might change the visibilities here, so prepare an empty app transition which
24087 // might be overridden later if we actually change visibilities.
24088 final boolean wasTransitionSet =
24089 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24090 if (!wasTransitionSet) {
24091 mWindowManager.prepareAppTransition(TRANSIT_NONE,
24092 false /* alwaysKeepCurrent */);
24094 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24096 // If there was a transition set already we don't want to interfere with it as we
24097 // might be starting it too early.
24098 if (!wasTransitionSet) {
24099 mWindowManager.executeAppTransition();
24102 if (callback != null) {
24108 public boolean isSystemReady() {
24109 // no need to synchronize(this) just to read & return the value
24110 return mSystemReady;
24114 public void notifyKeyguardTrustedChanged() {
24115 synchronized (ActivityManagerService.this) {
24116 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24117 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24123 * Sets if the given pid has an overlay UI or not.
24125 * @param pid The pid we are setting overlay UI for.
24126 * @param hasOverlayUi True if the process has overlay UI.
24127 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24130 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24131 synchronized (ActivityManagerService.this) {
24132 final ProcessRecord pr;
24133 synchronized (mPidsSelfLocked) {
24134 pr = mPidsSelfLocked.get(pid);
24136 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24140 if (pr.hasOverlayUi == hasOverlayUi) {
24143 pr.hasOverlayUi = hasOverlayUi;
24144 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24145 updateOomAdjLocked(pr, true);
24150 * Called after the network policy rules are updated by
24151 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24152 * and {@param procStateSeq}.
24155 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24156 if (DEBUG_NETWORK) {
24157 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24158 + uid + " seq: " + procStateSeq);
24161 synchronized (ActivityManagerService.this) {
24162 record = mActiveUids.get(uid);
24163 if (record == null) {
24164 if (DEBUG_NETWORK) {
24165 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24166 + " procStateSeq: " + procStateSeq);
24171 synchronized (record.networkStateLock) {
24172 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24173 if (DEBUG_NETWORK) {
24174 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24175 + " been handled for uid: " + uid);
24179 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24180 if (record.curProcStateSeq > procStateSeq) {
24181 if (DEBUG_NETWORK) {
24182 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24183 + ", curProcstateSeq: " + record.curProcStateSeq
24184 + ", procStateSeq: " + procStateSeq);
24188 if (record.waitingForNetwork) {
24189 if (DEBUG_NETWORK) {
24190 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24191 + ", procStateSeq: " + procStateSeq);
24193 record.networkStateLock.notifyAll();
24199 * Called after virtual display Id is updated by
24200 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24201 * {@param vrVr2dDisplayId}.
24204 public void setVr2dDisplayId(int vr2dDisplayId) {
24206 Slog.d(TAG, "setVr2dDisplayId called for: " +
24209 synchronized (ActivityManagerService.this) {
24210 mVr2dDisplayId = vr2dDisplayId;
24215 public void saveANRState(String reason) {
24216 synchronized (ActivityManagerService.this) {
24217 final StringWriter sw = new StringWriter();
24218 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24219 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24220 if (reason != null) {
24221 pw.println(" Reason: " + reason);
24224 mActivityStarter.dump(pw, " ", null);
24226 pw.println("-------------------------------------------------------------------------------");
24227 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24228 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24233 mLastANRState = sw.toString();
24238 public void clearSavedANRState() {
24239 synchronized (ActivityManagerService.this) {
24240 mLastANRState = null;
24245 public void setFocusedActivity(IBinder token) {
24246 synchronized (ActivityManagerService.this) {
24247 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24249 throw new IllegalArgumentException(
24250 "setFocusedActivity: No activity record matching token=" + token);
24252 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24253 r, "setFocusedActivity")) {
24254 mStackSupervisor.resumeFocusedStackTopActivityLocked();
24260 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24261 if (packageName == null) return false;
24263 synchronized (ActivityManagerService.this) {
24264 for (int i = 0; i < mLruProcesses.size(); i++) {
24265 final ProcessRecord processRecord = mLruProcesses.get(i);
24266 if (processRecord.uid == uid) {
24267 for (int j = 0; j < processRecord.activities.size(); j++) {
24268 final ActivityRecord activityRecord = processRecord.activities.get(j);
24269 if (packageName.equals(activityRecord.packageName)) {
24281 * Called by app main thread to wait for the network policy rules to get updated.
24283 * @param procStateSeq The sequence number indicating the process state change that the main
24284 * thread is interested in.
24287 public void waitForNetworkStateUpdate(long procStateSeq) {
24288 final int callingUid = Binder.getCallingUid();
24289 if (DEBUG_NETWORK) {
24290 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24293 synchronized (this) {
24294 record = mActiveUids.get(callingUid);
24295 if (record == null) {
24299 synchronized (record.networkStateLock) {
24300 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24301 if (DEBUG_NETWORK) {
24302 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24303 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24304 + " lastProcStateSeqDispatchedToObservers: "
24305 + record.lastDispatchedProcStateSeq);
24309 if (record.curProcStateSeq > procStateSeq) {
24310 if (DEBUG_NETWORK) {
24311 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24312 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24313 + ", procStateSeq: " + procStateSeq);
24317 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24318 if (DEBUG_NETWORK) {
24319 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24320 + procStateSeq + ", so no need to wait. Uid: "
24321 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24322 + record.lastNetworkUpdatedProcStateSeq);
24327 if (DEBUG_NETWORK) {
24328 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24329 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24331 final long startTime = SystemClock.uptimeMillis();
24332 record.waitingForNetwork = true;
24333 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24334 record.waitingForNetwork = false;
24335 final long totalTime = SystemClock.uptimeMillis() - startTime;
24336 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24337 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24338 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24339 + procStateSeq + " UidRec: " + record
24340 + " validateUidRec: " + mValidateUids.get(callingUid));
24342 } catch (InterruptedException e) {
24343 Thread.currentThread().interrupt();
24348 public void waitForBroadcastIdle(PrintWriter pw) {
24349 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24351 boolean idle = true;
24352 synchronized (this) {
24353 for (BroadcastQueue queue : mBroadcastQueues) {
24354 if (!queue.isIdle()) {
24355 final String msg = "Waiting for queue " + queue + " to become idle...";
24365 final String msg = "All broadcast queues are idle!";
24371 SystemClock.sleep(1000);
24377 * Return the user id of the last resumed activity.
24380 public @UserIdInt int getLastResumedActivityUserId() {
24381 enforceCallingPermission(
24382 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24383 synchronized (this) {
24384 if (mLastResumedActivity == null) {
24385 return mUserController.getCurrentUserIdLocked();
24387 return mLastResumedActivity.userId;
24392 * An implementation of IAppTask, that allows an app to manage its own tasks via
24393 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24394 * only the process that calls getAppTasks() can call the AppTask methods.
24396 class AppTaskImpl extends IAppTask.Stub {
24397 private int mTaskId;
24398 private int mCallingUid;
24400 public AppTaskImpl(int taskId, int callingUid) {
24402 mCallingUid = callingUid;
24405 private void checkCaller() {
24406 if (mCallingUid != Binder.getCallingUid()) {
24407 throw new SecurityException("Caller " + mCallingUid
24408 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24413 public void finishAndRemoveTask() {
24416 synchronized (ActivityManagerService.this) {
24417 long origId = Binder.clearCallingIdentity();
24419 // We remove the task from recents to preserve backwards
24420 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24421 REMOVE_FROM_RECENTS)) {
24422 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24425 Binder.restoreCallingIdentity(origId);
24431 public ActivityManager.RecentTaskInfo getTaskInfo() {
24434 synchronized (ActivityManagerService.this) {
24435 long origId = Binder.clearCallingIdentity();
24437 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24439 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24441 return createRecentTaskInfoFromTaskRecord(tr);
24443 Binder.restoreCallingIdentity(origId);
24449 public void moveToFront() {
24451 // Will bring task to front if it already has a root activity.
24452 final long origId = Binder.clearCallingIdentity();
24454 synchronized (this) {
24455 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24458 Binder.restoreCallingIdentity(origId);
24463 public int startActivity(IBinder whoThread, String callingPackage,
24464 Intent intent, String resolvedType, Bundle bOptions) {
24467 int callingUser = UserHandle.getCallingUserId();
24469 IApplicationThread appThread;
24470 synchronized (ActivityManagerService.this) {
24471 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24473 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24475 appThread = IApplicationThread.Stub.asInterface(whoThread);
24476 if (appThread == null) {
24477 throw new IllegalArgumentException("Bad app thread " + appThread);
24480 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24481 resolvedType, null, null, null, null, 0, 0, null, null,
24482 null, bOptions, false, callingUser, tr, "AppTaskImpl");
24486 public void setExcludeFromRecents(boolean exclude) {
24489 synchronized (ActivityManagerService.this) {
24490 long origId = Binder.clearCallingIdentity();
24492 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24494 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24496 Intent intent = tr.getBaseIntent();
24498 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24500 intent.setFlags(intent.getFlags()
24501 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24504 Binder.restoreCallingIdentity(origId);
24511 * Kill processes for the user with id userId and that depend on the package named packageName
24514 public void killPackageDependents(String packageName, int userId) {
24515 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24516 if (packageName == null) {
24517 throw new NullPointerException(
24518 "Cannot kill the dependents of a package without its name.");
24521 long callingId = Binder.clearCallingIdentity();
24522 IPackageManager pm = AppGlobals.getPackageManager();
24525 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24526 } catch (RemoteException e) {
24528 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24529 throw new IllegalArgumentException(
24530 "Cannot kill dependents of non-existing package " + packageName);
24533 synchronized(this) {
24534 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24535 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24536 "dep: " + packageName);
24539 Binder.restoreCallingIdentity(callingId);
24544 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24545 throws RemoteException {
24546 final long callingId = Binder.clearCallingIdentity();
24548 mKeyguardController.dismissKeyguard(token, callback);
24550 Binder.restoreCallingIdentity(callingId);
24555 public int restartUserInBackground(final int userId) {
24556 return mUserController.restartUser(userId, /* foreground */ false);
24560 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24561 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24562 "scheduleApplicationInfoChanged()");
24564 synchronized (this) {
24565 final long origId = Binder.clearCallingIdentity();
24567 updateApplicationInfoLocked(packageNames, userId);
24569 Binder.restoreCallingIdentity(origId);
24574 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24575 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24576 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24577 final ProcessRecord app = mLruProcesses.get(i);
24578 if (app.thread == null) {
24582 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24586 final int packageCount = app.pkgList.size();
24587 for (int j = 0; j < packageCount; j++) {
24588 final String packageName = app.pkgList.keyAt(j);
24589 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24591 final ApplicationInfo ai = AppGlobals.getPackageManager()
24592 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24594 app.thread.scheduleApplicationInfoChanged(ai);
24596 } catch (RemoteException e) {
24597 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24598 packageName, app));
24606 * Attach an agent to the specified process (proces name or PID)
24608 public void attachAgent(String process, String path) {
24610 synchronized (this) {
24611 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24612 if (proc == null || proc.thread == null) {
24613 throw new IllegalArgumentException("Unknown process: " + process);
24616 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24617 if (!isDebuggable) {
24618 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24619 throw new SecurityException("Process not debuggable: " + proc);
24623 proc.thread.attachAgent(path);
24625 } catch (RemoteException e) {
24626 throw new IllegalStateException("Process disappeared");
24631 public static class Injector {
24632 private NetworkManagementInternal mNmi;
24634 public Context getContext() {
24638 public AppOpsService getAppOpsService(File file, Handler handler) {
24639 return new AppOpsService(file, handler);
24642 public Handler getUiHandler(ActivityManagerService service) {
24643 return service.new UiHandler();
24646 public boolean isNetworkRestrictedForUid(int uid) {
24647 if (ensureHasNetworkManagementInternal()) {
24648 return mNmi.isNetworkRestrictedForUid(uid);
24653 private boolean ensureHasNetworkManagementInternal() {
24654 if (mNmi == null) {
24655 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24657 return mNmi != null;
24662 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24663 throws RemoteException {
24664 synchronized (this) {
24665 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24669 final long origId = Binder.clearCallingIdentity();
24671 r.setShowWhenLocked(showWhenLocked);
24673 Binder.restoreCallingIdentity(origId);
24679 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24680 synchronized (this) {
24681 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24685 final long origId = Binder.clearCallingIdentity();
24687 r.setTurnScreenOn(turnScreenOn);
24689 Binder.restoreCallingIdentity(origId);