2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import static android.Manifest.permission.CHANGE_CONFIGURATION;
20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25 import static android.Manifest.permission.READ_FRAME_BUFFER;
26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
32 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
35 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
36 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
37 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
38 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
39 import static android.content.pm.PackageManager.GET_PROVIDERS;
40 import static android.content.pm.PackageManager.MATCH_ANY_USER;
41 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
43 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
44 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
45 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
46 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
47 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
49 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
50 import static android.os.Build.VERSION_CODES.N;
51 import static android.os.Process.BLUETOOTH_UID;
52 import static android.os.Process.FIRST_APPLICATION_UID;
53 import static android.os.Process.FIRST_ISOLATED_UID;
54 import static android.os.Process.LAST_ISOLATED_UID;
55 import static android.os.Process.NFC_UID;
56 import static android.os.Process.PHONE_UID;
57 import static android.os.Process.PROC_CHAR;
58 import static android.os.Process.PROC_OUT_LONG;
59 import static android.os.Process.PROC_PARENS;
60 import static android.os.Process.PROC_SPACE_TERM;
61 import static android.os.Process.ProcessStartResult;
62 import static android.os.Process.ROOT_UID;
63 import static android.os.Process.SCHED_FIFO;
64 import static android.os.Process.SCHED_OTHER;
65 import static android.os.Process.SCHED_RESET_ON_FORK;
66 import static android.os.Process.SHELL_UID;
67 import static android.os.Process.SIGNAL_QUIT;
68 import static android.os.Process.SIGNAL_USR1;
69 import static android.os.Process.SYSTEM_UID;
70 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
71 import static android.os.Process.THREAD_GROUP_DEFAULT;
72 import static android.os.Process.THREAD_GROUP_TOP_APP;
73 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
74 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
75 import static android.os.Process.getFreeMemory;
76 import static android.os.Process.getTotalMemory;
77 import static android.os.Process.isThreadInProcess;
78 import static android.os.Process.killProcess;
79 import static android.os.Process.killProcessQuiet;
80 import static android.os.Process.myPid;
81 import static android.os.Process.myUid;
82 import static android.os.Process.readProcFile;
83 import static android.os.Process.removeAllProcessGroups;
84 import static android.os.Process.sendSignal;
85 import static android.os.Process.setProcessGroup;
86 import static android.os.Process.setThreadPriority;
87 import static android.os.Process.setThreadScheduler;
88 import static android.os.Process.startWebView;
89 import static android.os.Process.zygoteProcess;
90 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
91 import static android.provider.Settings.Global.DEBUG_APP;
92 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
94 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
95 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
96 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
97 import static android.provider.Settings.System.FONT_SCALE;
98 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
99 import static android.text.format.DateUtils.DAY_IN_MILLIS;
100 import static android.view.Display.DEFAULT_DISPLAY;
101 import static android.view.Display.INVALID_DISPLAY;
102 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
103 import static com.android.internal.util.XmlUtils.readIntAttribute;
104 import static com.android.internal.util.XmlUtils.readLongAttribute;
105 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
106 import static com.android.internal.util.XmlUtils.writeIntAttribute;
107 import static com.android.internal.util.XmlUtils.writeLongAttribute;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
165 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
167 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188 import static org.xmlpull.v1.XmlPullParser.START_TAG;
190 import android.Manifest;
191 import android.Manifest.permission;
192 import android.annotation.NonNull;
193 import android.annotation.Nullable;
194 import android.annotation.UserIdInt;
195 import android.app.Activity;
196 import android.app.ActivityManager;
197 import android.app.ActivityManager.RunningTaskInfo;
198 import android.app.ActivityManager.StackId;
199 import android.app.ActivityManager.StackInfo;
200 import android.app.ActivityManager.TaskSnapshot;
201 import android.app.ActivityManager.TaskThumbnailInfo;
202 import android.app.ActivityManagerInternal;
203 import android.app.ActivityManagerInternal.ScreenObserver;
204 import android.app.ActivityManagerInternal.SleepToken;
205 import android.app.ActivityOptions;
206 import android.app.ActivityThread;
207 import android.app.AlertDialog;
208 import android.app.AppGlobals;
209 import android.app.AppOpsManager;
210 import android.app.ApplicationErrorReport;
211 import android.app.ApplicationThreadConstants;
212 import android.app.BroadcastOptions;
213 import android.app.ContentProviderHolder;
214 import android.app.Dialog;
215 import android.app.IActivityController;
216 import android.app.IActivityManager;
217 import android.app.IAppTask;
218 import android.app.IApplicationThread;
219 import android.app.IInstrumentationWatcher;
220 import android.app.INotificationManager;
221 import android.app.IProcessObserver;
222 import android.app.IServiceConnection;
223 import android.app.IStopUserCallback;
224 import android.app.ITaskStackListener;
225 import android.app.IUiAutomationConnection;
226 import android.app.IUidObserver;
227 import android.app.IUserSwitchObserver;
228 import android.app.Instrumentation;
229 import android.app.Notification;
230 import android.app.NotificationManager;
231 import android.app.PendingIntent;
232 import android.app.PictureInPictureParams;
233 import android.app.ProfilerInfo;
234 import android.app.RemoteAction;
235 import android.app.WaitResult;
236 import android.app.admin.DevicePolicyManager;
237 import android.app.assist.AssistContent;
238 import android.app.assist.AssistStructure;
239 import android.app.backup.IBackupManager;
240 import android.app.usage.UsageEvents;
241 import android.app.usage.UsageStatsManagerInternal;
242 import android.appwidget.AppWidgetManager;
243 import android.content.ActivityNotFoundException;
244 import android.content.BroadcastReceiver;
245 import android.content.ClipData;
246 import android.content.ComponentCallbacks2;
247 import android.content.ComponentName;
248 import android.content.ContentProvider;
249 import android.content.ContentResolver;
250 import android.content.Context;
251 import android.content.DialogInterface;
252 import android.content.IContentProvider;
253 import android.content.IIntentReceiver;
254 import android.content.IIntentSender;
255 import android.content.Intent;
256 import android.content.IntentFilter;
257 import android.content.pm.ActivityInfo;
258 import android.content.pm.ApplicationInfo;
259 import android.content.pm.ConfigurationInfo;
260 import android.content.pm.IPackageDataObserver;
261 import android.content.pm.IPackageManager;
262 import android.content.pm.InstrumentationInfo;
263 import android.content.pm.PackageInfo;
264 import android.content.pm.PackageManager;
265 import android.content.pm.PackageManager.NameNotFoundException;
266 import android.content.pm.PackageManagerInternal;
267 import android.content.pm.ParceledListSlice;
268 import android.content.pm.PathPermission;
269 import android.content.pm.PermissionInfo;
270 import android.content.pm.ProviderInfo;
271 import android.content.pm.ResolveInfo;
272 import android.content.pm.SELinuxUtil;
273 import android.content.pm.ServiceInfo;
274 import android.content.pm.UserInfo;
275 import android.content.res.CompatibilityInfo;
276 import android.content.res.Configuration;
277 import android.content.res.Resources;
278 import android.database.ContentObserver;
279 import android.graphics.Bitmap;
280 import android.graphics.Point;
281 import android.graphics.Rect;
282 import android.location.LocationManager;
283 import android.media.audiofx.AudioEffect;
284 import android.metrics.LogMaker;
285 import android.net.Proxy;
286 import android.net.ProxyInfo;
287 import android.net.Uri;
288 import android.os.BatteryStats;
289 import android.os.Binder;
290 import android.os.Build;
291 import android.os.Bundle;
292 import android.os.Debug;
293 import android.os.DropBoxManager;
294 import android.os.Environment;
295 import android.os.FactoryTest;
296 import android.os.FileObserver;
297 import android.os.FileUtils;
298 import android.os.Handler;
299 import android.os.IBinder;
300 import android.os.IDeviceIdentifiersPolicyService;
301 import android.os.IPermissionController;
302 import android.os.IProcessInfoService;
303 import android.os.IProgressListener;
304 import android.os.LocaleList;
305 import android.os.Looper;
306 import android.os.Message;
307 import android.os.Parcel;
308 import android.os.ParcelFileDescriptor;
309 import android.os.PersistableBundle;
310 import android.os.PowerManager;
311 import android.os.PowerManagerInternal;
312 import android.os.Process;
313 import android.os.RemoteCallbackList;
314 import android.os.RemoteException;
315 import android.os.ResultReceiver;
316 import android.os.ServiceManager;
317 import android.os.ShellCallback;
318 import android.os.StrictMode;
319 import android.os.SystemClock;
320 import android.os.SystemProperties;
321 import android.os.Trace;
322 import android.os.TransactionTooLargeException;
323 import android.os.UpdateLock;
324 import android.os.UserHandle;
325 import android.os.UserManager;
326 import android.os.WorkSource;
327 import android.os.storage.IStorageManager;
328 import android.os.storage.StorageManager;
329 import android.os.storage.StorageManagerInternal;
330 import android.provider.Downloads;
331 import android.provider.Settings;
332 import android.service.voice.IVoiceInteractionSession;
333 import android.service.voice.VoiceInteractionManagerInternal;
334 import android.service.voice.VoiceInteractionSession;
335 import android.telecom.TelecomManager;
336 import android.text.TextUtils;
337 import android.text.format.DateUtils;
338 import android.text.format.Time;
339 import android.text.style.SuggestionSpan;
340 import android.util.ArrayMap;
341 import android.util.ArraySet;
342 import android.util.AtomicFile;
343 import android.util.TimingsTraceLog;
344 import android.util.DebugUtils;
345 import android.util.DisplayMetrics;
346 import android.util.EventLog;
347 import android.util.Log;
348 import android.util.Pair;
349 import android.util.PrintWriterPrinter;
350 import android.util.Slog;
351 import android.util.SparseArray;
352 import android.util.SparseIntArray;
353 import android.util.TimeUtils;
354 import android.util.Xml;
355 import android.view.Gravity;
356 import android.view.LayoutInflater;
357 import android.view.View;
358 import android.view.WindowManager;
360 import com.android.server.job.JobSchedulerInternal;
361 import com.google.android.collect.Lists;
362 import com.google.android.collect.Maps;
364 import com.android.internal.R;
365 import com.android.internal.annotations.GuardedBy;
366 import com.android.internal.annotations.VisibleForTesting;
367 import com.android.internal.app.AssistUtils;
368 import com.android.internal.app.DumpHeapActivity;
369 import com.android.internal.app.IAppOpsCallback;
370 import com.android.internal.app.IAppOpsService;
371 import com.android.internal.app.IVoiceInteractor;
372 import com.android.internal.app.ProcessMap;
373 import com.android.internal.app.SystemUserHomeActivity;
374 import com.android.internal.app.procstats.ProcessStats;
375 import com.android.internal.logging.MetricsLogger;
376 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
377 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
378 import com.android.internal.notification.SystemNotificationChannels;
379 import com.android.internal.os.BackgroundThread;
380 import com.android.internal.os.BatteryStatsImpl;
381 import com.android.internal.os.IResultReceiver;
382 import com.android.internal.os.ProcessCpuTracker;
383 import com.android.internal.os.TransferPipe;
384 import com.android.internal.os.Zygote;
385 import com.android.internal.policy.IKeyguardDismissCallback;
386 import com.android.internal.telephony.TelephonyIntents;
387 import com.android.internal.util.ArrayUtils;
388 import com.android.internal.util.DumpUtils;
389 import com.android.internal.util.FastPrintWriter;
390 import com.android.internal.util.FastXmlSerializer;
391 import com.android.internal.util.MemInfoReader;
392 import com.android.internal.util.Preconditions;
393 import com.android.server.AppOpsService;
394 import com.android.server.AttributeCache;
395 import com.android.server.DeviceIdleController;
396 import com.android.server.IntentResolver;
397 import com.android.server.LocalServices;
398 import com.android.server.LockGuard;
399 import com.android.server.NetworkManagementInternal;
400 import com.android.server.RescueParty;
401 import com.android.server.ServiceThread;
402 import com.android.server.SystemConfig;
403 import com.android.server.SystemService;
404 import com.android.server.SystemServiceManager;
405 import com.android.server.ThreadPriorityBooster;
406 import com.android.server.Watchdog;
407 import com.android.server.am.ActivityStack.ActivityState;
408 import com.android.server.firewall.IntentFirewall;
409 import com.android.server.pm.Installer;
410 import com.android.server.pm.Installer.InstallerException;
411 import com.android.server.statusbar.StatusBarManagerInternal;
412 import com.android.server.vr.VrManagerInternal;
413 import com.android.server.wm.PinnedStackWindowController;
414 import com.android.server.wm.WindowManagerService;
416 import java.text.SimpleDateFormat;
417 import org.xmlpull.v1.XmlPullParser;
418 import org.xmlpull.v1.XmlPullParserException;
419 import org.xmlpull.v1.XmlSerializer;
422 import java.io.FileDescriptor;
423 import java.io.FileInputStream;
424 import java.io.FileNotFoundException;
425 import java.io.FileOutputStream;
426 import java.io.IOException;
427 import java.io.InputStreamReader;
428 import java.io.PrintWriter;
429 import java.io.StringWriter;
430 import java.io.UnsupportedEncodingException;
431 import java.lang.ref.WeakReference;
432 import java.nio.charset.StandardCharsets;
433 import java.text.DateFormat;
434 import java.util.ArrayList;
435 import java.util.Arrays;
436 import java.util.Collections;
437 import java.util.Comparator;
438 import java.util.Date;
439 import java.util.HashMap;
440 import java.util.HashSet;
441 import java.util.Iterator;
442 import java.util.List;
443 import java.util.Locale;
444 import java.util.Map;
445 import java.util.Objects;
446 import java.util.Set;
447 import java.util.concurrent.CountDownLatch;
448 import java.util.concurrent.atomic.AtomicBoolean;
449 import java.util.concurrent.atomic.AtomicLong;
451 import dalvik.system.VMRuntime;
452 import libcore.io.IoUtils;
453 import libcore.util.EmptyArray;
455 public class ActivityManagerService extends IActivityManager.Stub
456 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
459 * Priority we boost main thread and RT of top app to.
461 public static final int TOP_APP_PRIORITY_BOOST = -10;
463 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
464 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
465 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
466 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
467 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
468 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
469 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
470 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
471 private static final String TAG_LRU = TAG + POSTFIX_LRU;
472 private static final String TAG_MU = TAG + POSTFIX_MU;
473 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
474 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
475 private static final String TAG_POWER = TAG + POSTFIX_POWER;
476 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
477 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
478 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
479 private static final String TAG_PSS = TAG + POSTFIX_PSS;
480 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
481 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
482 private static final String TAG_STACK = TAG + POSTFIX_STACK;
483 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
484 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
485 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
486 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
488 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
489 // here so that while the job scheduler can depend on AMS, the other way around
490 // need not be the case.
491 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
493 /** Control over CPU and battery monitoring */
494 // write battery stats every 30 minutes.
495 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
496 static final boolean MONITOR_CPU_USAGE = true;
497 // don't sample cpu less than every 5 seconds.
498 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
499 // wait possibly forever for next cpu sample.
500 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
501 static final boolean MONITOR_THREAD_CPU_USAGE = false;
503 // The flags that are set for all calls we make to the package manager.
504 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
506 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
508 // Amount of time after a call to stopAppSwitches() during which we will
509 // prevent further untrusted switches from happening.
510 static final long APP_SWITCH_DELAY_TIME = 5*1000;
512 // How long we wait for a launched process to attach to the activity manager
513 // before we decide it's never going to come up for real.
514 static final int PROC_START_TIMEOUT = 10*1000;
515 // How long we wait for an attached process to publish its content providers
516 // before we decide it must be hung.
517 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
519 // How long we wait for a launched process to attach to the activity manager
520 // before we decide it's never going to come up for real, when the process was
521 // started with a wrapper for instrumentation (such as Valgrind) because it
522 // could take much longer than usual.
523 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
525 // How long we allow a receiver to run before giving up on it.
526 static final int BROADCAST_FG_TIMEOUT = 10*1000;
527 static final int BROADCAST_BG_TIMEOUT = 60*1000;
529 // How long we wait until we timeout on key dispatching.
530 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
532 // How long we wait until we timeout on key dispatching during instrumentation.
533 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
535 // How long to wait in getAssistContextExtras for the activity and foreground services
536 // to respond with the result.
537 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
539 // How long top wait when going through the modern assist (which doesn't need to block
540 // on getting this result before starting to launch its UI).
541 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
543 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
544 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
546 // Maximum number of persisted Uri grants a package is allowed
547 static final int MAX_PERSISTED_URI_GRANTS = 128;
549 static final int MY_PID = myPid();
551 static final String[] EMPTY_STRING_ARRAY = new String[0];
553 // How many bytes to write into the dropbox log before truncating
554 static final int DROPBOX_MAX_SIZE = 192 * 1024;
555 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
556 // as one line, but close enough for now.
557 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
559 // Access modes for handleIncomingUser.
560 static final int ALLOW_NON_FULL = 0;
561 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
562 static final int ALLOW_FULL_ONLY = 2;
564 // Necessary ApplicationInfo flags to mark an app as persistent
565 private static final int PERSISTENT_MASK =
566 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
568 // Intent sent when remote bugreport collection has been completed
569 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
570 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
572 // Used to indicate that an app transition should be animated.
573 static final boolean ANIMATE = true;
575 // Determines whether to take full screen screenshots
576 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
579 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
581 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
584 * State indicating that there is no need for any blocking for network.
587 static final int NETWORK_STATE_NO_CHANGE = 0;
590 * State indicating that the main thread needs to be informed about the network wait.
593 static final int NETWORK_STATE_BLOCK = 1;
596 * State indicating that any threads waiting for network state to get updated can be unblocked.
599 static final int NETWORK_STATE_UNBLOCK = 2;
601 // Max character limit for a notification title. If the notification title is larger than this
602 // the notification will not be legible to the user.
603 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
605 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
607 /** All system services */
608 SystemServiceManager mSystemServiceManager;
609 AssistUtils mAssistUtils;
611 private Installer mInstaller;
613 /** Run all ActivityStacks through this */
614 final ActivityStackSupervisor mStackSupervisor;
615 private final KeyguardController mKeyguardController;
617 final ActivityStarter mActivityStarter;
619 final TaskChangeNotificationController mTaskChangeNotificationController;
621 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
623 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
625 public final IntentFirewall mIntentFirewall;
627 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
628 // default action automatically. Important for devices without direct input
630 private boolean mShowDialogs = true;
632 private final VrController mVrController;
634 // VR Vr2d Display Id.
635 int mVr2dDisplayId = INVALID_DISPLAY;
637 // Whether we should use SCHED_FIFO for UI and RenderThreads.
638 private boolean mUseFifoUiScheduling = false;
640 BroadcastQueue mFgBroadcastQueue;
641 BroadcastQueue mBgBroadcastQueue;
642 // Convenient for easy iteration over the queues. Foreground is first
643 // so that dispatch of foreground broadcasts gets precedence.
644 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
646 BroadcastStats mLastBroadcastStats;
647 BroadcastStats mCurBroadcastStats;
649 BroadcastQueue broadcastQueueForIntent(Intent intent) {
650 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
651 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
652 "Broadcast intent " + intent + " on "
653 + (isFg ? "foreground" : "background") + " queue");
654 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
658 * The last resumed activity. This is identical to the current resumed activity most
659 * of the time but could be different when we're pausing one activity before we resume
662 private ActivityRecord mLastResumedActivity;
665 * If non-null, we are tracking the time the user spends in the currently focused app.
667 private AppTimeTracker mCurAppTimeTracker;
670 * List of intents that were used to start the most recent tasks.
672 final RecentTasks mRecentTasks;
675 * For addAppTask: cached of the last activity component that was added.
677 ComponentName mLastAddedTaskComponent;
680 * For addAppTask: cached of the last activity uid that was added.
682 int mLastAddedTaskUid;
685 * For addAppTask: cached of the last ActivityInfo that was added.
687 ActivityInfo mLastAddedTaskActivity;
690 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
692 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
695 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
697 String mDeviceOwnerName;
699 final UserController mUserController;
701 final AppErrors mAppErrors;
704 * Dump of the activity state at the time of the last ANR. Cleared after
705 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
707 String mLastANRState;
710 * Indicates the maximum time spent waiting for the network rules to get updated.
713 long mWaitForNetworkTimeoutMs;
715 public boolean canShowErrorDialogs() {
716 return mShowDialogs && !mSleeping && !mShuttingDown
717 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
718 && !(UserManager.isDeviceInDemoMode(mContext)
719 && mUserController.getCurrentUser().isDemo());
722 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
723 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
725 static void boostPriorityForLockedSection() {
726 sThreadPriorityBooster.boost();
729 static void resetPriorityAfterLockedSection() {
730 sThreadPriorityBooster.reset();
733 public class PendingAssistExtras extends Binder implements Runnable {
734 public final ActivityRecord activity;
735 public boolean isHome;
736 public final Bundle extras;
737 public final Intent intent;
738 public final String hint;
739 public final IResultReceiver receiver;
740 public final int userHandle;
741 public boolean haveResult = false;
742 public Bundle result = null;
743 public AssistStructure structure = null;
744 public AssistContent content = null;
745 public Bundle receiverExtras;
747 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
748 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
749 activity = _activity;
753 receiver = _receiver;
754 receiverExtras = _receiverExtras;
755 userHandle = _userHandle;
760 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
761 synchronized (this) {
765 pendingAssistExtrasTimedOut(this);
769 final ArrayList<PendingAssistExtras> mPendingAssistExtras
770 = new ArrayList<PendingAssistExtras>();
773 * Process management.
775 final ProcessList mProcessList = new ProcessList();
778 * All of the applications we currently have running organized by name.
779 * The keys are strings of the application package name (as
780 * returned by the package manager), and the keys are ApplicationRecord
783 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
786 * Tracking long-term execution of processes to look for abuse and other
789 final ProcessStatsService mProcessStats;
792 * The currently running isolated processes.
794 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
797 * Counter for assigning isolated process uids, to avoid frequently reusing the
800 int mNextIsolatedProcessUid = 0;
803 * The currently running heavy-weight process, if any.
805 ProcessRecord mHeavyWeightProcess = null;
808 * Non-persistent appId whitelist for background restrictions
810 int[] mBackgroundAppIdWhitelist = new int[] {
815 * Broadcast actions that will always be deliverable to unlaunched/background apps
817 ArraySet<String> mBackgroundLaunchBroadcasts;
820 * All of the processes we currently have running organized by pid.
821 * The keys are the pid running the application.
823 * <p>NOTE: This object is protected by its own lock, NOT the global
824 * activity manager lock!
826 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
829 * All of the processes that have been forced to be important. The key
830 * is the pid of the caller who requested it (we hold a death
833 abstract class ImportanceToken implements IBinder.DeathRecipient {
838 ImportanceToken(int _pid, IBinder _token, String _reason) {
845 public String toString() {
846 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
847 + " " + reason + " " + pid + " " + token + " }";
850 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
853 * List of records for processes that someone had tried to start before the
854 * system was ready. We don't start them at that point, but ensure they
855 * are started by the time booting is complete.
857 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
860 * List of persistent applications that are in the process
863 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
866 * Processes that are being forcibly torn down.
868 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
871 * List of running applications, sorted by recent usage.
872 * The first entry in the list is the least recently used.
874 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
877 * Where in mLruProcesses that the processes hosting activities start.
879 int mLruProcessActivityStart = 0;
882 * Where in mLruProcesses that the processes hosting services start.
883 * This is after (lower index) than mLruProcessesActivityStart.
885 int mLruProcessServiceStart = 0;
888 * List of processes that should gc as soon as things are idle.
890 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
893 * Processes we want to collect PSS data from.
895 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
897 private boolean mBinderTransactionTrackingEnabled = false;
900 * Last time we requested PSS data of all processes.
902 long mLastFullPssTime = SystemClock.uptimeMillis();
905 * If set, the next time we collect PSS data we should do a full collection
906 * with data from native processes and the kernel.
908 boolean mFullPssPending = false;
911 * This is the process holding what we currently consider to be
912 * the "home" activity.
914 ProcessRecord mHomeProcess;
917 * This is the process holding the activity the user last visited that
918 * is in a different process from the one they are currently in.
920 ProcessRecord mPreviousProcess;
923 * The time at which the previous process was last visible.
925 long mPreviousProcessVisibleTime;
928 * Track all uids that have actively running processes.
930 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
933 * This is for verifying the UID report flow.
935 static final boolean VALIDATE_UID_STATES = true;
936 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
939 * Packages that the user has asked to have run in screen size
940 * compatibility mode instead of filling the screen.
942 final CompatModePackages mCompatModePackages;
945 * Set of IntentSenderRecord objects that are currently active.
947 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
948 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
951 * Fingerprints (hashCode()) of stack traces that we've
952 * already logged DropBox entries for. Guarded by itself. If
953 * something (rogue user app) forces this over
954 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
956 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
957 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
960 * Strict Mode background batched logging state.
962 * The string buffer is guarded by itself, and its lock is also
963 * used to determine if another batched write is already
966 private final StringBuilder mStrictModeBuffer = new StringBuilder();
969 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
970 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
972 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
975 * Resolver for broadcast intents to registered receivers.
976 * Holds BroadcastFilter (subclass of IntentFilter).
978 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
979 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
981 protected boolean allowFilterResult(
982 BroadcastFilter filter, List<BroadcastFilter> dest) {
983 IBinder target = filter.receiverList.receiver.asBinder();
984 for (int i = dest.size() - 1; i >= 0; i--) {
985 if (dest.get(i).receiverList.receiver.asBinder() == target) {
993 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
994 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
995 || userId == filter.owningUserId) {
996 return super.newResult(filter, match, userId);
1002 protected BroadcastFilter[] newArray(int size) {
1003 return new BroadcastFilter[size];
1007 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1008 return packageName.equals(filter.packageName);
1013 * State of all active sticky broadcasts per user. Keys are the action of the
1014 * sticky Intent, values are an ArrayList of all broadcasted intents with
1015 * that action (which should usually be one). The SparseArray is keyed
1016 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1017 * for stickies that are sent to all users.
1019 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1020 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1022 final ActiveServices mServices;
1024 final static class Association {
1025 final int mSourceUid;
1026 final String mSourceProcess;
1027 final int mTargetUid;
1028 final ComponentName mTargetComponent;
1029 final String mTargetProcess;
1037 // states of the source process when the bind occurred.
1038 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1039 long mLastStateUptime;
1040 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1041 - ActivityManager.MIN_PROCESS_STATE+1];
1043 Association(int sourceUid, String sourceProcess, int targetUid,
1044 ComponentName targetComponent, String targetProcess) {
1045 mSourceUid = sourceUid;
1046 mSourceProcess = sourceProcess;
1047 mTargetUid = targetUid;
1048 mTargetComponent = targetComponent;
1049 mTargetProcess = targetProcess;
1054 * When service association tracking is enabled, this is all of the associations we
1055 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1056 * -> association data.
1058 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1059 mAssociations = new SparseArray<>();
1060 boolean mTrackingAssociations;
1063 * Backup/restore process management
1065 String mBackupAppName = null;
1066 BackupRecord mBackupTarget = null;
1068 final ProviderMap mProviderMap;
1071 * List of content providers who have clients waiting for them. The
1072 * application is currently being launched and the provider will be
1073 * removed from this list once it is published.
1075 final ArrayList<ContentProviderRecord> mLaunchingProviders
1076 = new ArrayList<ContentProviderRecord>();
1079 * File storing persisted {@link #mGrantedUriPermissions}.
1081 private final AtomicFile mGrantFile;
1083 /** XML constants used in {@link #mGrantFile} */
1084 private static final String TAG_URI_GRANTS = "uri-grants";
1085 private static final String TAG_URI_GRANT = "uri-grant";
1086 private static final String ATTR_USER_HANDLE = "userHandle";
1087 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1088 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1089 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1090 private static final String ATTR_TARGET_PKG = "targetPkg";
1091 private static final String ATTR_URI = "uri";
1092 private static final String ATTR_MODE_FLAGS = "modeFlags";
1093 private static final String ATTR_CREATED_TIME = "createdTime";
1094 private static final String ATTR_PREFIX = "prefix";
1097 * Global set of specific {@link Uri} permissions that have been granted.
1098 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1099 * to {@link UriPermission#uri} to {@link UriPermission}.
1102 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1103 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1105 public static class GrantUri {
1106 public final int sourceUserId;
1107 public final Uri uri;
1108 public boolean prefix;
1110 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1111 this.sourceUserId = sourceUserId;
1113 this.prefix = prefix;
1117 public int hashCode() {
1119 hashCode = 31 * hashCode + sourceUserId;
1120 hashCode = 31 * hashCode + uri.hashCode();
1121 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1126 public boolean equals(Object o) {
1127 if (o instanceof GrantUri) {
1128 GrantUri other = (GrantUri) o;
1129 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1130 && prefix == other.prefix;
1136 public String toString() {
1137 String result = uri.toString() + " [user " + sourceUserId + "]";
1138 if (prefix) result += " [prefix]";
1142 public String toSafeString() {
1143 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1144 if (prefix) result += " [prefix]";
1148 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1149 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1150 ContentProvider.getUriWithoutUserId(uri), false);
1154 CoreSettingsObserver mCoreSettingsObserver;
1156 FontScaleSettingObserver mFontScaleSettingObserver;
1158 private final class FontScaleSettingObserver extends ContentObserver {
1159 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1161 public FontScaleSettingObserver() {
1163 ContentResolver resolver = mContext.getContentResolver();
1164 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1168 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1169 if (mFontScaleUri.equals(uri)) {
1170 updateFontScaleIfNeeded(userId);
1176 * Thread-local storage used to carry caller permissions over through
1177 * indirect content-provider access.
1179 private class Identity {
1180 public final IBinder token;
1181 public final int pid;
1182 public final int uid;
1184 Identity(IBinder _token, int _pid, int _uid) {
1191 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1194 * All information we have collected about the runtime performance of
1195 * any user id that can impact battery performance.
1197 final BatteryStatsService mBatteryStatsService;
1200 * Information about component usage
1202 UsageStatsManagerInternal mUsageStatsService;
1205 * Access to DeviceIdleController service.
1207 DeviceIdleController.LocalService mLocalDeviceIdleController;
1210 * Set of app ids that are whitelisted for device idle and thus background check.
1212 int[] mDeviceIdleWhitelist = new int[0];
1215 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1217 int[] mDeviceIdleTempWhitelist = new int[0];
1219 static final class PendingTempWhitelist {
1220 final int targetUid;
1221 final long duration;
1224 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1225 targetUid = _targetUid;
1226 duration = _duration;
1231 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1234 * Information about and control over application operations
1236 final AppOpsService mAppOpsService;
1238 /** Current sequencing integer of the configuration, for skipping old configurations. */
1239 private int mConfigurationSeq;
1242 * Temp object used when global and/or display override configuration is updated. It is also
1243 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1246 private Configuration mTempConfig = new Configuration();
1248 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1249 new UpdateConfigurationResult();
1250 private static final class UpdateConfigurationResult {
1251 // Configuration changes that were updated.
1253 // If the activity was relaunched to match the new configuration.
1254 boolean activityRelaunched;
1258 activityRelaunched = false;
1262 boolean mSuppressResizeConfigChanges;
1265 * Hardware-reported OpenGLES version.
1267 final int GL_ES_VERSION;
1270 * List of initialization arguments to pass to all processes when binding applications to them.
1271 * For example, references to the commonly used services.
1273 HashMap<String, IBinder> mAppBindArgs;
1274 HashMap<String, IBinder> mIsolatedAppBindArgs;
1277 * Temporary to avoid allocations. Protected by main lock.
1279 final StringBuilder mStringBuilder = new StringBuilder(256);
1282 * Used to control how we initialize the service.
1284 ComponentName mTopComponent;
1285 String mTopAction = Intent.ACTION_MAIN;
1288 volatile boolean mProcessesReady = false;
1289 volatile boolean mSystemReady = false;
1290 volatile boolean mOnBattery = false;
1291 volatile int mFactoryTest;
1293 @GuardedBy("this") boolean mBooting = false;
1294 @GuardedBy("this") boolean mCallFinishBooting = false;
1295 @GuardedBy("this") boolean mBootAnimationComplete = false;
1296 @GuardedBy("this") boolean mLaunchWarningShown = false;
1297 @GuardedBy("this") boolean mCheckedForSetup = false;
1299 final Context mContext;
1302 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1303 * change at runtime. Use mContext for non-UI purposes.
1305 final Context mUiContext;
1308 * The time at which we will allow normal application switches again,
1309 * after a call to {@link #stopAppSwitches()}.
1311 long mAppSwitchesAllowedTime;
1314 * This is set to true after the first switch after mAppSwitchesAllowedTime
1315 * is set; any switches after that will clear the time.
1317 boolean mDidAppSwitch;
1320 * Last time (in uptime) at which we checked for power usage.
1322 long mLastPowerCheckUptime;
1325 * Set while we are wanting to sleep, to prevent any
1326 * activities from being started/resumed.
1328 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1330 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1331 * while in the sleep state until there is a pending transition out of sleep, in which case
1332 * mSleeping is set to false, and remains false while awake.
1334 * Whether mSleeping can quickly toggled between true/false without the device actually
1335 * display changing states is undefined.
1337 private boolean mSleeping = false;
1340 * The process state used for processes that are running the top activities.
1341 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1343 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1346 * Set while we are running a voice interaction. This overrides
1347 * sleeping while it is active.
1349 IVoiceInteractionSession mRunningVoice;
1352 * For some direct access we need to power manager.
1354 PowerManagerInternal mLocalPowerManager;
1357 * We want to hold a wake lock while running a voice interaction session, since
1358 * this may happen with the screen off and we need to keep the CPU running to
1359 * be able to continue to interact with the user.
1361 PowerManager.WakeLock mVoiceWakeLock;
1364 * State of external calls telling us if the device is awake or asleep.
1366 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1369 * Set if we are shutting down the system, similar to sleeping.
1371 boolean mShuttingDown = false;
1374 * Current sequence id for oom_adj computation traversal.
1379 * Current sequence id for process LRU updating.
1384 * Keep track of the non-cached/empty process we last found, to help
1385 * determine how to distribute cached/empty processes next time.
1387 int mNumNonCachedProcs = 0;
1390 * Keep track of the number of cached hidden procs, to balance oom adj
1391 * distribution between those and empty procs.
1393 int mNumCachedHiddenProcs = 0;
1396 * Keep track of the number of service processes we last found, to
1397 * determine on the next iteration which should be B services.
1399 int mNumServiceProcs = 0;
1400 int mNewNumAServiceProcs = 0;
1401 int mNewNumServiceProcs = 0;
1404 * Allow the current computed overall memory level of the system to go down?
1405 * This is set to false when we are killing processes for reasons other than
1406 * memory management, so that the now smaller process list will not be taken as
1407 * an indication that memory is tighter.
1409 boolean mAllowLowerMemLevel = false;
1412 * The last computed memory level, for holding when we are in a state that
1413 * processes are going away for other reasons.
1415 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1418 * The last total number of process we have, to determine if changes actually look
1419 * like a shrinking number of process due to lower RAM.
1421 int mLastNumProcesses;
1424 * The uptime of the last time we performed idle maintenance.
1426 long mLastIdleTime = SystemClock.uptimeMillis();
1429 * Total time spent with RAM that has been added in the past since the last idle time.
1431 long mLowRamTimeSinceLastIdle = 0;
1434 * If RAM is currently low, when that horrible situation started.
1436 long mLowRamStartTime = 0;
1439 * For reporting to battery stats the current top application.
1441 private String mCurResumedPackage = null;
1442 private int mCurResumedUid = -1;
1445 * For reporting to battery stats the apps currently running foreground
1446 * service. The ProcessMap is package/uid tuples; each of these contain
1447 * an array of the currently foreground processes.
1449 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1450 = new ProcessMap<ArrayList<ProcessRecord>>();
1453 * Set if the systemServer made a call to enterSafeMode.
1458 * If true, we are running under a test environment so will sample PSS from processes
1459 * much more rapidly to try to collect better data when the tests are rapidly
1460 * running through apps.
1462 boolean mTestPssMode = false;
1464 String mDebugApp = null;
1465 boolean mWaitForDebugger = false;
1466 boolean mDebugTransient = false;
1467 String mOrigDebugApp = null;
1468 boolean mOrigWaitForDebugger = false;
1469 boolean mAlwaysFinishActivities = false;
1470 boolean mForceResizableActivities;
1472 * Flag that indicates if multi-window is enabled.
1474 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1475 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1476 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1477 * At least one of the forms of multi-window must be enabled in order for this flag to be
1478 * initialized to 'true'.
1480 * @see #mSupportsSplitScreenMultiWindow
1481 * @see #mSupportsFreeformWindowManagement
1482 * @see #mSupportsPictureInPicture
1483 * @see #mSupportsMultiDisplay
1485 boolean mSupportsMultiWindow;
1486 boolean mSupportsSplitScreenMultiWindow;
1487 boolean mSupportsFreeformWindowManagement;
1488 boolean mSupportsPictureInPicture;
1489 boolean mSupportsMultiDisplay;
1490 boolean mSupportsLeanbackOnly;
1491 IActivityController mController = null;
1492 boolean mControllerIsAMonkey = false;
1493 String mProfileApp = null;
1494 ProcessRecord mProfileProc = null;
1495 ProfilerInfo mProfilerInfo = null;
1496 int mProfileType = 0;
1497 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1498 String mMemWatchDumpProcName;
1499 String mMemWatchDumpFile;
1500 int mMemWatchDumpPid;
1501 int mMemWatchDumpUid;
1502 String mTrackAllocationApp = null;
1503 String mNativeDebuggingApp = null;
1505 final long[] mTmpLong = new long[2];
1507 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1510 * A global counter for generating sequence numbers.
1511 * This value will be used when incrementing sequence numbers in individual uidRecords.
1513 * Having a global counter ensures that seq numbers are monotonically increasing for a
1514 * particular uid even when the uidRecord is re-created.
1518 long mProcStateSeqCounter = 0;
1520 private final Injector mInjector;
1522 static final class ProcessChangeItem {
1523 static final int CHANGE_ACTIVITIES = 1<<0;
1528 boolean foregroundActivities;
1531 static final class UidObserverRegistration {
1537 final SparseIntArray lastProcStates;
1539 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1543 cutpoint = _cutpoint;
1544 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1545 lastProcStates = new SparseIntArray();
1547 lastProcStates = null;
1552 final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1554 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1555 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1557 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1558 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1560 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1561 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1563 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1564 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1566 OomAdjObserver mCurOomAdjObserver;
1569 interface OomAdjObserver {
1570 void onOomAdjMessage(String msg);
1574 * Runtime CPU use collection thread. This object's lock is used to
1575 * perform synchronization with the thread (notifying it to run).
1577 final Thread mProcessCpuThread;
1580 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1581 * Must acquire this object's lock when accessing it.
1582 * NOTE: this lock will be held while doing long operations (trawling
1583 * through all processes in /proc), so it should never be acquired by
1584 * any critical paths such as when holding the main activity manager lock.
1586 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1587 MONITOR_THREAD_CPU_USAGE);
1588 final AtomicLong mLastCpuTime = new AtomicLong(0);
1589 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1590 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1592 long mLastWriteTime = 0;
1595 * Used to retain an update lock when the foreground activity is in
1598 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1601 * Set to true after the system has finished booting.
1603 boolean mBooted = false;
1605 WindowManagerService mWindowManager;
1606 final ActivityThread mSystemThread;
1608 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1609 final ProcessRecord mApp;
1611 final IApplicationThread mAppThread;
1613 AppDeathRecipient(ProcessRecord app, int pid,
1614 IApplicationThread thread) {
1615 if (DEBUG_ALL) Slog.v(
1616 TAG, "New death recipient " + this
1617 + " for thread " + thread.asBinder());
1620 mAppThread = thread;
1624 public void binderDied() {
1625 if (DEBUG_ALL) Slog.v(
1626 TAG, "Death received in " + this
1627 + " for thread " + mAppThread.asBinder());
1628 synchronized(ActivityManagerService.this) {
1629 appDiedLocked(mApp, mPid, mAppThread, true);
1634 static final int SHOW_ERROR_UI_MSG = 1;
1635 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1636 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1637 static final int UPDATE_CONFIGURATION_MSG = 4;
1638 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1639 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1640 static final int SERVICE_TIMEOUT_MSG = 12;
1641 static final int UPDATE_TIME_ZONE = 13;
1642 static final int SHOW_UID_ERROR_UI_MSG = 14;
1643 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1644 static final int PROC_START_TIMEOUT_MSG = 20;
1645 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1646 static final int KILL_APPLICATION_MSG = 22;
1647 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1648 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1649 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1650 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1651 static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1652 static final int CLEAR_DNS_CACHE_MSG = 28;
1653 static final int UPDATE_HTTP_PROXY_MSG = 29;
1654 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1655 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1656 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1657 static final int REPORT_MEM_USAGE_MSG = 33;
1658 static final int REPORT_USER_SWITCH_MSG = 34;
1659 static final int CONTINUE_USER_SWITCH_MSG = 35;
1660 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1661 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1662 static final int PERSIST_URI_GRANTS_MSG = 38;
1663 static final int REQUEST_ALL_PSS_MSG = 39;
1664 static final int START_PROFILES_MSG = 40;
1665 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1666 static final int SYSTEM_USER_START_MSG = 42;
1667 static final int SYSTEM_USER_CURRENT_MSG = 43;
1668 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1669 static final int FINISH_BOOTING_MSG = 45;
1670 static final int START_USER_SWITCH_UI_MSG = 46;
1671 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1672 static final int DISMISS_DIALOG_UI_MSG = 48;
1673 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1674 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1675 static final int DELETE_DUMPHEAP_MSG = 51;
1676 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1677 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1678 static final int REPORT_TIME_TRACKER_MSG = 54;
1679 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1680 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1681 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1682 static final int IDLE_UIDS_MSG = 58;
1683 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1684 static final int LOG_STACK_STATE = 60;
1685 static final int VR_MODE_CHANGE_MSG = 61;
1686 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1687 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1688 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1689 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1690 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1691 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1692 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1693 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1694 static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1695 static final int DISPATCH_SCREEN_AWAKE_MSG = 71;
1696 static final int DISPATCH_SCREEN_KEYGUARD_MSG = 72;
1697 static final int START_USER_SWITCH_FG_MSG = 712;
1698 static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1700 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1701 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1702 static final int FIRST_COMPAT_MODE_MSG = 300;
1703 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1705 static ServiceThread sKillThread = null;
1706 static KillHandler sKillHandler = null;
1708 CompatModeDialog mCompatModeDialog;
1709 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1710 long mLastMemUsageReportTime = 0;
1713 * Flag whether the current user is a "monkey", i.e. whether
1714 * the UI is driven by a UI automation tool.
1716 private boolean mUserIsMonkey;
1718 /** Flag whether the device has a Recents UI */
1719 boolean mHasRecents;
1721 /** The dimensions of the thumbnails in the Recents UI. */
1722 int mThumbnailWidth;
1723 int mThumbnailHeight;
1724 float mFullscreenThumbnailScale;
1726 final ServiceThread mHandlerThread;
1727 final MainHandler mHandler;
1728 final Handler mUiHandler;
1730 final ActivityManagerConstants mConstants;
1732 PackageManagerInternal mPackageManagerInt;
1734 // VoiceInteraction session ID that changes for each new request except when
1735 // being called for multiwindow assist in a single session.
1736 private int mViSessionId = 1000;
1738 final boolean mPermissionReviewRequired;
1740 private static String sTheRealBuildSerial = Build.UNKNOWN;
1743 * Current global configuration information. Contains general settings for the entire system,
1744 * also corresponds to the merged configuration of the default display.
1746 Configuration getGlobalConfiguration() {
1747 return mStackSupervisor.getConfiguration();
1750 final class KillHandler extends Handler {
1751 static final int KILL_PROCESS_GROUP_MSG = 4000;
1753 public KillHandler(Looper looper) {
1754 super(looper, null, true);
1758 public void handleMessage(Message msg) {
1760 case KILL_PROCESS_GROUP_MSG:
1762 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1763 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1764 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1769 super.handleMessage(msg);
1774 final class UiHandler extends Handler {
1775 public UiHandler() {
1776 super(com.android.server.UiThread.get().getLooper(), null, true);
1780 public void handleMessage(Message msg) {
1782 case SHOW_ERROR_UI_MSG: {
1783 mAppErrors.handleShowAppErrorUi(msg);
1784 ensureBootCompleted();
1786 case SHOW_NOT_RESPONDING_UI_MSG: {
1787 mAppErrors.handleShowAnrUi(msg);
1788 ensureBootCompleted();
1790 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1791 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1792 synchronized (ActivityManagerService.this) {
1793 ProcessRecord proc = (ProcessRecord) data.get("app");
1795 Slog.e(TAG, "App not found when showing strict mode dialog.");
1798 if (proc.crashDialog != null) {
1799 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1802 AppErrorResult res = (AppErrorResult) data.get("result");
1803 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1804 Dialog d = new StrictModeViolationDialog(mUiContext,
1805 ActivityManagerService.this, res, proc);
1807 proc.crashDialog = d;
1809 // The device is asleep, so just pretend that the user
1810 // saw a crash dialog and hit "force quit".
1814 ensureBootCompleted();
1816 case SHOW_FACTORY_ERROR_UI_MSG: {
1817 Dialog d = new FactoryErrorDialog(
1818 mUiContext, msg.getData().getCharSequence("msg"));
1820 ensureBootCompleted();
1822 case WAIT_FOR_DEBUGGER_UI_MSG: {
1823 synchronized (ActivityManagerService.this) {
1824 ProcessRecord app = (ProcessRecord)msg.obj;
1825 if (msg.arg1 != 0) {
1826 if (!app.waitedForDebugger) {
1827 Dialog d = new AppWaitingForDebuggerDialog(
1828 ActivityManagerService.this,
1831 app.waitedForDebugger = true;
1835 if (app.waitDialog != null) {
1836 app.waitDialog.dismiss();
1837 app.waitDialog = null;
1842 case SHOW_UID_ERROR_UI_MSG: {
1844 AlertDialog d = new BaseErrorDialog(mUiContext);
1845 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1846 d.setCancelable(false);
1847 d.setTitle(mUiContext.getText(R.string.android_system_label));
1848 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1849 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1850 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1854 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1856 AlertDialog d = new BaseErrorDialog(mUiContext);
1857 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1858 d.setCancelable(false);
1859 d.setTitle(mUiContext.getText(R.string.android_system_label));
1860 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1861 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1862 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1866 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1867 synchronized (ActivityManagerService.this) {
1868 ActivityRecord ar = (ActivityRecord) msg.obj;
1869 if (mCompatModeDialog != null) {
1870 if (mCompatModeDialog.mAppInfo.packageName.equals(
1871 ar.info.applicationInfo.packageName)) {
1874 mCompatModeDialog.dismiss();
1875 mCompatModeDialog = null;
1877 if (ar != null && false) {
1878 if (mCompatModePackages.getPackageAskCompatModeLocked(
1880 int mode = mCompatModePackages.computeCompatModeLocked(
1881 ar.info.applicationInfo);
1882 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1883 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1884 mCompatModeDialog = new CompatModeDialog(
1885 ActivityManagerService.this, mUiContext,
1886 ar.info.applicationInfo);
1887 mCompatModeDialog.show();
1894 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1895 synchronized (ActivityManagerService.this) {
1896 final ActivityRecord ar = (ActivityRecord) msg.obj;
1897 if (mUnsupportedDisplaySizeDialog != null) {
1898 mUnsupportedDisplaySizeDialog.dismiss();
1899 mUnsupportedDisplaySizeDialog = null;
1901 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1903 // TODO(multi-display): Show dialog on appropriate display.
1904 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1905 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1906 mUnsupportedDisplaySizeDialog.show();
1911 case START_USER_SWITCH_UI_MSG: {
1912 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1915 case DISMISS_DIALOG_UI_MSG: {
1916 final Dialog d = (Dialog) msg.obj;
1920 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1921 dispatchProcessesChanged();
1924 case DISPATCH_PROCESS_DIED_UI_MSG: {
1925 final int pid = msg.arg1;
1926 final int uid = msg.arg2;
1927 dispatchProcessDied(pid, uid);
1930 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1931 dispatchUidsChanged();
1933 case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1934 dispatchOomAdjObserver((String)msg.obj);
1936 case PUSH_TEMP_WHITELIST_UI_MSG: {
1937 pushTempWhitelist();
1943 final class MainHandler extends Handler {
1944 public MainHandler(Looper looper) {
1945 super(looper, null, true);
1949 public void handleMessage(Message msg) {
1951 case UPDATE_CONFIGURATION_MSG: {
1952 final ContentResolver resolver = mContext.getContentResolver();
1953 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1956 case GC_BACKGROUND_PROCESSES_MSG: {
1957 synchronized (ActivityManagerService.this) {
1958 performAppGcsIfAppropriateLocked();
1961 case SERVICE_TIMEOUT_MSG: {
1962 mServices.serviceTimeout((ProcessRecord)msg.obj);
1964 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1965 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1967 case SERVICE_FOREGROUND_CRASH_MSG: {
1968 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1970 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1971 RemoteCallbackList<IResultReceiver> callbacks
1972 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1973 int N = callbacks.beginBroadcast();
1974 for (int i = 0; i < N; i++) {
1976 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1977 } catch (RemoteException e) {
1980 callbacks.finishBroadcast();
1982 case UPDATE_TIME_ZONE: {
1983 synchronized (ActivityManagerService.this) {
1984 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1985 ProcessRecord r = mLruProcesses.get(i);
1986 if (r.thread != null) {
1988 r.thread.updateTimeZone();
1989 } catch (RemoteException ex) {
1990 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1996 case CLEAR_DNS_CACHE_MSG: {
1997 synchronized (ActivityManagerService.this) {
1998 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1999 ProcessRecord r = mLruProcesses.get(i);
2000 if (r.thread != null) {
2002 r.thread.clearDnsCache();
2003 } catch (RemoteException ex) {
2004 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2010 case UPDATE_HTTP_PROXY_MSG: {
2011 ProxyInfo proxy = (ProxyInfo)msg.obj;
2014 String exclList = "";
2015 Uri pacFileUrl = Uri.EMPTY;
2016 if (proxy != null) {
2017 host = proxy.getHost();
2018 port = Integer.toString(proxy.getPort());
2019 exclList = proxy.getExclusionListAsString();
2020 pacFileUrl = proxy.getPacFileUrl();
2022 synchronized (ActivityManagerService.this) {
2023 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2024 ProcessRecord r = mLruProcesses.get(i);
2025 if (r.thread != null) {
2027 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2028 } catch (RemoteException ex) {
2029 Slog.w(TAG, "Failed to update http proxy for: " +
2030 r.info.processName);
2036 case PROC_START_TIMEOUT_MSG: {
2037 ProcessRecord app = (ProcessRecord)msg.obj;
2038 synchronized (ActivityManagerService.this) {
2039 processStartTimedOutLocked(app);
2042 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2043 ProcessRecord app = (ProcessRecord)msg.obj;
2044 synchronized (ActivityManagerService.this) {
2045 processContentProviderPublishTimedOutLocked(app);
2048 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2049 synchronized (ActivityManagerService.this) {
2050 mActivityStarter.doPendingActivityLaunchesLocked(true);
2053 case KILL_APPLICATION_MSG: {
2054 synchronized (ActivityManagerService.this) {
2055 final int appId = msg.arg1;
2056 final int userId = msg.arg2;
2057 Bundle bundle = (Bundle)msg.obj;
2058 String pkg = bundle.getString("pkg");
2059 String reason = bundle.getString("reason");
2060 forceStopPackageLocked(pkg, appId, false, false, true, false,
2061 false, userId, reason);
2064 case FINALIZE_PENDING_INTENT_MSG: {
2065 ((PendingIntentRecord)msg.obj).completeFinalize();
2067 case POST_HEAVY_NOTIFICATION_MSG: {
2068 INotificationManager inm = NotificationManager.getService();
2073 ActivityRecord root = (ActivityRecord)msg.obj;
2074 ProcessRecord process = root.app;
2075 if (process == null) {
2080 Context context = mContext.createPackageContext(process.info.packageName, 0);
2081 String text = mContext.getString(R.string.heavy_weight_notification,
2082 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2083 Notification notification =
2084 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2085 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2089 .setColor(mContext.getColor(
2090 com.android.internal.R.color.system_notification_accent_color))
2091 .setContentTitle(text)
2093 mContext.getText(R.string.heavy_weight_notification_detail))
2094 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2095 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2096 new UserHandle(root.userId)))
2099 inm.enqueueNotificationWithTag("android", "android", null,
2100 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2101 notification, root.userId);
2102 } catch (RuntimeException e) {
2103 Slog.w(ActivityManagerService.TAG,
2104 "Error showing notification for heavy-weight app", e);
2105 } catch (RemoteException e) {
2107 } catch (NameNotFoundException e) {
2108 Slog.w(TAG, "Unable to create context for heavy notification", e);
2111 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2112 INotificationManager inm = NotificationManager.getService();
2117 inm.cancelNotificationWithTag("android", null,
2118 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2119 } catch (RuntimeException e) {
2120 Slog.w(ActivityManagerService.TAG,
2121 "Error canceling notification for service", e);
2122 } catch (RemoteException e) {
2125 case CHECK_EXCESSIVE_POWER_USE_MSG: {
2126 synchronized (ActivityManagerService.this) {
2127 checkExcessivePowerUsageLocked();
2128 removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2129 Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2130 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2133 case REPORT_MEM_USAGE_MSG: {
2134 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2135 Thread thread = new Thread() {
2136 @Override public void run() {
2137 reportMemUsage(memInfos);
2143 case START_USER_SWITCH_FG_MSG: {
2144 mUserController.startUserInForeground(msg.arg1);
2147 case REPORT_USER_SWITCH_MSG: {
2148 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2151 case CONTINUE_USER_SWITCH_MSG: {
2152 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2155 case USER_SWITCH_TIMEOUT_MSG: {
2156 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2159 case IMMERSIVE_MODE_LOCK_MSG: {
2160 final boolean nextState = (msg.arg1 != 0);
2161 if (mUpdateLock.isHeld() != nextState) {
2162 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2163 "Applying new update lock state '" + nextState
2164 + "' for " + (ActivityRecord)msg.obj);
2166 mUpdateLock.acquire();
2168 mUpdateLock.release();
2173 case PERSIST_URI_GRANTS_MSG: {
2174 writeGrantedUriPermissions();
2177 case REQUEST_ALL_PSS_MSG: {
2178 synchronized (ActivityManagerService.this) {
2179 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2183 case START_PROFILES_MSG: {
2184 synchronized (ActivityManagerService.this) {
2185 mUserController.startProfilesLocked();
2189 case UPDATE_TIME_PREFERENCE_MSG: {
2190 // The user's time format preference might have changed.
2191 // For convenience we re-use the Intent extra values.
2192 synchronized (ActivityManagerService.this) {
2193 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2194 ProcessRecord r = mLruProcesses.get(i);
2195 if (r.thread != null) {
2197 r.thread.updateTimePrefs(msg.arg1);
2198 } catch (RemoteException ex) {
2199 Slog.w(TAG, "Failed to update preferences for: "
2200 + r.info.processName);
2207 case SYSTEM_USER_START_MSG: {
2208 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2209 Integer.toString(msg.arg1), msg.arg1);
2210 mSystemServiceManager.startUser(msg.arg1);
2213 case SYSTEM_USER_UNLOCK_MSG: {
2214 final int userId = msg.arg1;
2215 mSystemServiceManager.unlockUser(userId);
2216 synchronized (ActivityManagerService.this) {
2217 mRecentTasks.loadUserRecentsLocked(userId);
2219 if (userId == UserHandle.USER_SYSTEM) {
2220 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2222 installEncryptionUnawareProviders(userId);
2223 mUserController.finishUserUnlocked((UserState) msg.obj);
2226 case SYSTEM_USER_CURRENT_MSG: {
2227 mBatteryStatsService.noteEvent(
2228 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2229 Integer.toString(msg.arg2), msg.arg2);
2230 mBatteryStatsService.noteEvent(
2231 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2232 Integer.toString(msg.arg1), msg.arg1);
2233 mSystemServiceManager.switchUser(msg.arg1);
2236 case ENTER_ANIMATION_COMPLETE_MSG: {
2237 synchronized (ActivityManagerService.this) {
2238 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2239 if (r != null && r.app != null && r.app.thread != null) {
2241 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2242 } catch (RemoteException e) {
2248 case FINISH_BOOTING_MSG: {
2249 if (msg.arg1 != 0) {
2250 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2252 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2254 if (msg.arg2 != 0) {
2255 enableScreenAfterBoot();
2259 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2261 Locale l = (Locale) msg.obj;
2262 IBinder service = ServiceManager.getService("mount");
2263 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2264 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2265 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2266 } catch (RemoteException e) {
2267 Log.e(TAG, "Error storing locale for decryption UI", e);
2271 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2272 final int uid = msg.arg1;
2273 final byte[] firstPacket = (byte[]) msg.obj;
2275 synchronized (mPidsSelfLocked) {
2276 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2277 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2280 p.thread.notifyCleartextNetwork(firstPacket);
2281 } catch (RemoteException ignored) {
2288 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2289 final String procName;
2291 final long memLimit;
2292 final String reportPackage;
2293 synchronized (ActivityManagerService.this) {
2294 procName = mMemWatchDumpProcName;
2295 uid = mMemWatchDumpUid;
2296 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2298 val = mMemWatchProcesses.get(procName, 0);
2301 memLimit = val.first;
2302 reportPackage = val.second;
2305 reportPackage = null;
2308 if (procName == null) {
2312 if (DEBUG_PSS) Slog.d(TAG_PSS,
2313 "Showing dump heap notification from " + procName + "/" + uid);
2315 INotificationManager inm = NotificationManager.getService();
2320 String text = mContext.getString(R.string.dump_heap_notification, procName);
2323 Intent deleteIntent = new Intent();
2324 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2325 Intent intent = new Intent();
2326 intent.setClassName("android", DumpHeapActivity.class.getName());
2327 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2328 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2329 if (reportPackage != null) {
2330 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2332 int userId = UserHandle.getUserId(uid);
2333 Notification notification =
2334 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2335 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2338 .setAutoCancel(true)
2340 .setColor(mContext.getColor(
2341 com.android.internal.R.color.system_notification_accent_color))
2342 .setContentTitle(text)
2344 mContext.getText(R.string.dump_heap_notification_detail))
2345 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2346 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2347 new UserHandle(userId)))
2348 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2349 deleteIntent, 0, UserHandle.SYSTEM))
2353 inm.enqueueNotificationWithTag("android", "android", null,
2354 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2355 notification, userId);
2356 } catch (RuntimeException e) {
2357 Slog.w(ActivityManagerService.TAG,
2358 "Error showing notification for dump heap", e);
2359 } catch (RemoteException e) {
2362 case DELETE_DUMPHEAP_MSG: {
2363 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2364 null, DumpHeapActivity.JAVA_URI,
2365 Intent.FLAG_GRANT_READ_URI_PERMISSION
2366 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2367 UserHandle.myUserId());
2368 synchronized (ActivityManagerService.this) {
2369 mMemWatchDumpFile = null;
2370 mMemWatchDumpProcName = null;
2371 mMemWatchDumpPid = -1;
2372 mMemWatchDumpUid = -1;
2375 case FOREGROUND_PROFILE_CHANGED_MSG: {
2376 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2378 case REPORT_TIME_TRACKER_MSG: {
2379 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2380 tracker.deliverResult(mContext);
2382 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2383 mUserController.dispatchUserSwitchComplete(msg.arg1);
2385 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2386 mUserController.dispatchLockedBootComplete(msg.arg1);
2388 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2389 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2391 connection.shutdown();
2392 } catch (RemoteException e) {
2393 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2395 // Only a UiAutomation can set this flag and now that
2396 // it is finished we make sure it is reset to its default.
2397 mUserIsMonkey = false;
2399 case IDLE_UIDS_MSG: {
2402 case VR_MODE_CHANGE_MSG: {
2403 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2406 synchronized (ActivityManagerService.this) {
2407 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2408 mWindowManager.disableNonVrUi(disableNonVrUi);
2409 if (disableNonVrUi) {
2410 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2411 // then remove the pinned stack.
2412 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2414 if (pinnedStack != null) {
2415 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2420 case DISPATCH_SCREEN_AWAKE_MSG: {
2421 final boolean isAwake = msg.arg1 != 0;
2422 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2423 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2426 case DISPATCH_SCREEN_KEYGUARD_MSG: {
2427 final boolean isShowing = msg.arg1 != 0;
2428 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2429 mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2432 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2433 synchronized (ActivityManagerService.this) {
2434 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2435 ProcessRecord r = mLruProcesses.get(i);
2436 if (r.thread != null) {
2438 r.thread.handleTrustStorageUpdate();
2439 } catch (RemoteException ex) {
2440 Slog.w(TAG, "Failed to handle trust storage update for: " +
2441 r.info.processName);
2451 static final int COLLECT_PSS_BG_MSG = 1;
2453 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2455 public void handleMessage(Message msg) {
2457 case COLLECT_PSS_BG_MSG: {
2458 long start = SystemClock.uptimeMillis();
2459 MemInfoReader memInfo = null;
2460 synchronized (ActivityManagerService.this) {
2461 if (mFullPssPending) {
2462 mFullPssPending = false;
2463 memInfo = new MemInfoReader();
2466 if (memInfo != null) {
2467 updateCpuStatsNow();
2468 long nativeTotalPss = 0;
2469 final List<ProcessCpuTracker.Stats> stats;
2470 synchronized (mProcessCpuTracker) {
2471 stats = mProcessCpuTracker.getStats( (st)-> {
2472 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2475 final int N = stats.size();
2476 for (int j = 0; j < N; j++) {
2477 synchronized (mPidsSelfLocked) {
2478 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2479 // This is one of our own processes; skip it.
2483 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2485 memInfo.readMemInfo();
2486 synchronized (ActivityManagerService.this) {
2487 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2488 + (SystemClock.uptimeMillis()-start) + "ms");
2489 final long cachedKb = memInfo.getCachedSizeKb();
2490 final long freeKb = memInfo.getFreeSizeKb();
2491 final long zramKb = memInfo.getZramTotalSizeKb();
2492 final long kernelKb = memInfo.getKernelUsedSizeKb();
2493 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2494 kernelKb*1024, nativeTotalPss*1024);
2495 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2501 long[] tmp = new long[2];
2507 synchronized (ActivityManagerService.this) {
2508 if (mPendingPssProcesses.size() <= 0) {
2509 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2510 "Collected PSS of " + num + " processes in "
2511 + (SystemClock.uptimeMillis() - start) + "ms");
2512 mPendingPssProcesses.clear();
2515 proc = mPendingPssProcesses.remove(0);
2516 procState = proc.pssProcState;
2517 lastPssTime = proc.lastPssTime;
2518 if (proc.thread != null && procState == proc.setProcState
2519 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2520 < SystemClock.uptimeMillis()) {
2528 long pss = Debug.getPss(pid, tmp, null);
2529 synchronized (ActivityManagerService.this) {
2530 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2531 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2533 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2534 SystemClock.uptimeMillis());
2544 public void setSystemProcess() {
2546 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2547 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2548 ServiceManager.addService("meminfo", new MemBinder(this));
2549 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2550 ServiceManager.addService("dbinfo", new DbBinder(this));
2551 if (MONITOR_CPU_USAGE) {
2552 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2554 ServiceManager.addService("permission", new PermissionController(this));
2555 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2557 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2558 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2559 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2561 synchronized (this) {
2562 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2563 app.persistent = true;
2565 app.maxAdj = ProcessList.SYSTEM_ADJ;
2566 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2567 synchronized (mPidsSelfLocked) {
2568 mPidsSelfLocked.put(app.pid, app);
2570 updateLruProcessLocked(app, false, null);
2571 updateOomAdjLocked();
2573 } catch (PackageManager.NameNotFoundException e) {
2574 throw new RuntimeException(
2575 "Unable to find android system package", e);
2579 public void setWindowManager(WindowManagerService wm) {
2580 mWindowManager = wm;
2581 mStackSupervisor.setWindowManager(wm);
2582 mActivityStarter.setWindowManager(wm);
2585 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2586 mUsageStatsService = usageStatsManager;
2589 public void startObservingNativeCrashes() {
2590 final NativeCrashListener ncl = new NativeCrashListener(this);
2594 public IAppOpsService getAppOpsService() {
2595 return mAppOpsService;
2598 static class MemBinder extends Binder {
2599 ActivityManagerService mActivityManagerService;
2600 MemBinder(ActivityManagerService activityManagerService) {
2601 mActivityManagerService = activityManagerService;
2605 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2606 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2607 "meminfo", pw)) return;
2608 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2612 static class GraphicsBinder extends Binder {
2613 ActivityManagerService mActivityManagerService;
2614 GraphicsBinder(ActivityManagerService activityManagerService) {
2615 mActivityManagerService = activityManagerService;
2619 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2620 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2621 "gfxinfo", pw)) return;
2622 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2626 static class DbBinder extends Binder {
2627 ActivityManagerService mActivityManagerService;
2628 DbBinder(ActivityManagerService activityManagerService) {
2629 mActivityManagerService = activityManagerService;
2633 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2634 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2635 "dbinfo", pw)) return;
2636 mActivityManagerService.dumpDbInfo(fd, pw, args);
2640 static class CpuBinder extends Binder {
2641 ActivityManagerService mActivityManagerService;
2642 CpuBinder(ActivityManagerService activityManagerService) {
2643 mActivityManagerService = activityManagerService;
2647 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2648 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2649 "cpuinfo", pw)) return;
2650 synchronized (mActivityManagerService.mProcessCpuTracker) {
2651 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2652 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2653 SystemClock.uptimeMillis()));
2658 public static final class Lifecycle extends SystemService {
2659 private final ActivityManagerService mService;
2661 public Lifecycle(Context context) {
2663 mService = new ActivityManagerService(context);
2667 public void onStart() {
2672 public void onCleanupUser(int userId) {
2673 mService.mBatteryStatsService.onCleanupUser(userId);
2676 public ActivityManagerService getService() {
2682 public ActivityManagerService(Injector injector) {
2683 mInjector = injector;
2684 mContext = mInjector.getContext();
2687 mActivityStarter = null;
2689 mAppOpsService = mInjector.getAppOpsService(null, null);
2690 mBatteryStatsService = null;
2691 mCompatModePackages = null;
2695 mHandlerThread = null;
2696 mIntentFirewall = null;
2697 mKeyguardController = null;
2698 mPermissionReviewRequired = false;
2699 mProcessCpuThread = null;
2700 mProcessStats = null;
2701 mProviderMap = null;
2702 mRecentTasks = null;
2704 mStackSupervisor = null;
2705 mSystemThread = null;
2706 mTaskChangeNotificationController = null;
2707 mUiHandler = injector.getUiHandler(null);
2708 mUserController = null;
2709 mVrController = null;
2712 // Note: This method is invoked on the main thread but may need to attach various
2713 // handlers to other threads. So take care to be explicit about the looper.
2714 public ActivityManagerService(Context systemContext) {
2715 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2716 mInjector = new Injector();
2717 mContext = systemContext;
2719 mFactoryTest = FactoryTest.getMode();
2720 mSystemThread = ActivityThread.currentActivityThread();
2721 mUiContext = mSystemThread.getSystemUiContext();
2723 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2725 mPermissionReviewRequired = mContext.getResources().getBoolean(
2726 com.android.internal.R.bool.config_permissionReviewRequired);
2728 mHandlerThread = new ServiceThread(TAG,
2729 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2730 mHandlerThread.start();
2731 mHandler = new MainHandler(mHandlerThread.getLooper());
2732 mUiHandler = mInjector.getUiHandler(this);
2734 mConstants = new ActivityManagerConstants(this, mHandler);
2736 /* static; one-time init here */
2737 if (sKillHandler == null) {
2738 sKillThread = new ServiceThread(TAG + ":kill",
2739 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2740 sKillThread.start();
2741 sKillHandler = new KillHandler(sKillThread.getLooper());
2744 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2745 "foreground", BROADCAST_FG_TIMEOUT, false);
2746 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2747 "background", BROADCAST_BG_TIMEOUT, true);
2748 mBroadcastQueues[0] = mFgBroadcastQueue;
2749 mBroadcastQueues[1] = mBgBroadcastQueue;
2751 mServices = new ActiveServices(this);
2752 mProviderMap = new ProviderMap(this);
2753 mAppErrors = new AppErrors(mUiContext, this);
2755 // TODO: Move creation of battery stats service outside of activity manager service.
2756 File dataDir = Environment.getDataDirectory();
2757 File systemDir = new File(dataDir, "system");
2759 mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2760 mBatteryStatsService.getActiveStatistics().readLocked();
2761 mBatteryStatsService.scheduleWriteToDisk();
2762 mOnBattery = DEBUG_POWER ? true
2763 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2764 mBatteryStatsService.getActiveStatistics().setCallback(this);
2766 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2768 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2769 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2770 new IAppOpsCallback.Stub() {
2771 @Override public void opChanged(int op, int uid, String packageName) {
2772 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2773 if (mAppOpsService.checkOperation(op, uid, packageName)
2774 != AppOpsManager.MODE_ALLOWED) {
2775 runInBackgroundDisabled(uid);
2781 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2783 mUserController = new UserController(this);
2785 mVrController = new VrController(this);
2787 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2788 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2790 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2791 mUseFifoUiScheduling = true;
2794 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2795 mTempConfig.setToDefaults();
2796 mTempConfig.setLocales(LocaleList.getDefault());
2797 mConfigurationSeq = mTempConfig.seq = 1;
2798 mStackSupervisor = createStackSupervisor();
2799 mStackSupervisor.onConfigurationChanged(mTempConfig);
2800 mKeyguardController = mStackSupervisor.mKeyguardController;
2801 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2802 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2803 mTaskChangeNotificationController =
2804 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2805 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2806 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2808 mProcessCpuThread = new Thread("CpuTracker") {
2811 synchronized (mProcessCpuTracker) {
2812 mProcessCpuInitLatch.countDown();
2813 mProcessCpuTracker.init();
2818 synchronized(this) {
2819 final long now = SystemClock.uptimeMillis();
2820 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2821 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2822 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2823 // + ", write delay=" + nextWriteDelay);
2824 if (nextWriteDelay < nextCpuDelay) {
2825 nextCpuDelay = nextWriteDelay;
2827 if (nextCpuDelay > 0) {
2828 mProcessCpuMutexFree.set(true);
2829 this.wait(nextCpuDelay);
2832 } catch (InterruptedException e) {
2834 updateCpuStatsNow();
2835 } catch (Exception e) {
2836 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2842 Watchdog.getInstance().addMonitor(this);
2843 Watchdog.getInstance().addThread(mHandler);
2846 protected ActivityStackSupervisor createStackSupervisor() {
2847 return new ActivityStackSupervisor(this, mHandler.getLooper());
2850 public void setSystemServiceManager(SystemServiceManager mgr) {
2851 mSystemServiceManager = mgr;
2854 public void setInstaller(Installer installer) {
2855 mInstaller = installer;
2858 private void start() {
2859 removeAllProcessGroups();
2860 mProcessCpuThread.start();
2862 mBatteryStatsService.publish();
2863 mAppOpsService.publish(mContext);
2864 Slog.d("AppOps", "AppOpsService published");
2865 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2866 // Wait for the synchronized block started in mProcessCpuThread,
2867 // so that any other acccess to mProcessCpuTracker from main thread
2868 // will be blocked during mProcessCpuTracker initialization.
2870 mProcessCpuInitLatch.await();
2871 } catch (InterruptedException e) {
2872 Slog.wtf(TAG, "Interrupted wait during start", e);
2873 Thread.currentThread().interrupt();
2874 throw new IllegalStateException("Interrupted wait during start");
2878 void onUserStoppedLocked(int userId) {
2879 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2882 public void initPowerManagement() {
2883 mStackSupervisor.initPowerManagement();
2884 mBatteryStatsService.initPowerManagement();
2885 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2886 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2887 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2888 mVoiceWakeLock.setReferenceCounted(false);
2891 private ArraySet<String> getBackgroundLaunchBroadcasts() {
2892 if (mBackgroundLaunchBroadcasts == null) {
2893 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2895 return mBackgroundLaunchBroadcasts;
2899 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2900 throws RemoteException {
2901 if (code == SYSPROPS_TRANSACTION) {
2902 // We need to tell all apps about the system property change.
2903 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2904 synchronized(this) {
2905 final int NP = mProcessNames.getMap().size();
2906 for (int ip=0; ip<NP; ip++) {
2907 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2908 final int NA = apps.size();
2909 for (int ia=0; ia<NA; ia++) {
2910 ProcessRecord app = apps.valueAt(ia);
2911 if (app.thread != null) {
2912 procs.add(app.thread.asBinder());
2918 int N = procs.size();
2919 for (int i=0; i<N; i++) {
2920 Parcel data2 = Parcel.obtain();
2922 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2923 Binder.FLAG_ONEWAY);
2924 } catch (RemoteException e) {
2930 return super.onTransact(code, data, reply, flags);
2931 } catch (RuntimeException e) {
2932 // The activity manager only throws security exceptions, so let's
2934 if (!(e instanceof SecurityException)) {
2935 Slog.wtf(TAG, "Activity Manager Crash."
2936 + " UID:" + Binder.getCallingUid()
2937 + " PID:" + Binder.getCallingPid()
2938 + " TRANS:" + code, e);
2944 void updateCpuStats() {
2945 final long now = SystemClock.uptimeMillis();
2946 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2949 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2950 synchronized (mProcessCpuThread) {
2951 mProcessCpuThread.notify();
2956 void updateCpuStatsNow() {
2957 synchronized (mProcessCpuTracker) {
2958 mProcessCpuMutexFree.set(false);
2959 final long now = SystemClock.uptimeMillis();
2960 boolean haveNewCpuStats = false;
2962 if (MONITOR_CPU_USAGE &&
2963 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2964 mLastCpuTime.set(now);
2965 mProcessCpuTracker.update();
2966 if (mProcessCpuTracker.hasGoodLastStats()) {
2967 haveNewCpuStats = true;
2968 //Slog.i(TAG, mProcessCpu.printCurrentState());
2969 //Slog.i(TAG, "Total CPU usage: "
2970 // + mProcessCpu.getTotalCpuPercent() + "%");
2972 // Slog the cpu usage if the property is set.
2973 if ("true".equals(SystemProperties.get("events.cpu"))) {
2974 int user = mProcessCpuTracker.getLastUserTime();
2975 int system = mProcessCpuTracker.getLastSystemTime();
2976 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2977 int irq = mProcessCpuTracker.getLastIrqTime();
2978 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2979 int idle = mProcessCpuTracker.getLastIdleTime();
2981 int total = user + system + iowait + irq + softIrq + idle;
2982 if (total == 0) total = 1;
2984 EventLog.writeEvent(EventLogTags.CPU,
2985 ((user+system+iowait+irq+softIrq) * 100) / total,
2986 (user * 100) / total,
2987 (system * 100) / total,
2988 (iowait * 100) / total,
2989 (irq * 100) / total,
2990 (softIrq * 100) / total);
2995 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2996 synchronized(bstats) {
2997 synchronized(mPidsSelfLocked) {
2998 if (haveNewCpuStats) {
2999 if (bstats.startAddingCpuLocked()) {
3002 final int N = mProcessCpuTracker.countStats();
3003 for (int i=0; i<N; i++) {
3004 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3008 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3009 totalUTime += st.rel_utime;
3010 totalSTime += st.rel_stime;
3012 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3013 if (ps == null || !ps.isActive()) {
3014 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3015 pr.info.uid, pr.processName);
3017 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3018 pr.curCpuTime += st.rel_utime + st.rel_stime;
3019 if (pr.lastCpuTime == 0) {
3020 pr.lastCpuTime = pr.curCpuTime;
3023 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3024 if (ps == null || !ps.isActive()) {
3025 st.batteryStats = ps = bstats.getProcessStatsLocked(
3026 bstats.mapUid(st.uid), st.name);
3028 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3031 final int userTime = mProcessCpuTracker.getLastUserTime();
3032 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3033 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3034 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3035 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3036 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3037 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3038 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3043 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3044 mLastWriteTime = now;
3045 mBatteryStatsService.scheduleWriteToDisk();
3052 public void batteryNeedsCpuUpdate() {
3053 updateCpuStatsNow();
3057 public void batteryPowerChanged(boolean onBattery) {
3058 // When plugging in, update the CPU stats first before changing
3060 updateCpuStatsNow();
3061 synchronized (this) {
3062 synchronized(mPidsSelfLocked) {
3063 mOnBattery = DEBUG_POWER ? true : onBattery;
3069 public void batterySendBroadcast(Intent intent) {
3070 synchronized (this) {
3071 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3072 AppOpsManager.OP_NONE, null, false, false,
3073 -1, SYSTEM_UID, UserHandle.USER_ALL);
3078 * Initialize the application bind args. These are passed to each
3079 * process when the bindApplication() IPC is sent to the process. They're
3080 * lazily setup to make sure the services are running when they're asked for.
3082 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3083 // Isolated processes won't get this optimization, so that we don't
3084 // violate the rules about which services they have access to.
3086 if (mIsolatedAppBindArgs == null) {
3087 mIsolatedAppBindArgs = new HashMap<>();
3088 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3090 return mIsolatedAppBindArgs;
3093 if (mAppBindArgs == null) {
3094 mAppBindArgs = new HashMap<>();
3096 // Setup the application init args
3097 mAppBindArgs.put("package", ServiceManager.getService("package"));
3098 mAppBindArgs.put("window", ServiceManager.getService("window"));
3099 mAppBindArgs.put(Context.ALARM_SERVICE,
3100 ServiceManager.getService(Context.ALARM_SERVICE));
3102 return mAppBindArgs;
3106 * Update AMS states when an activity is resumed. This should only be called by
3107 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3109 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3110 final TaskRecord task = r.getTask();
3111 if (task.isApplicationTask()) {
3112 if (mCurAppTimeTracker != r.appTimeTracker) {
3113 // We are switching app tracking. Complete the current one.
3114 if (mCurAppTimeTracker != null) {
3115 mCurAppTimeTracker.stop();
3116 mHandler.obtainMessage(
3117 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3118 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3119 mCurAppTimeTracker = null;
3121 if (r.appTimeTracker != null) {
3122 mCurAppTimeTracker = r.appTimeTracker;
3123 startTimeTrackingFocusedActivityLocked();
3126 startTimeTrackingFocusedActivityLocked();
3129 r.appTimeTracker = null;
3131 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3132 // TODO: Probably not, because we don't want to resume voice on switching
3133 // back to this activity
3134 if (task.voiceInteractor != null) {
3135 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3137 finishRunningVoiceLocked();
3139 if (mLastResumedActivity != null) {
3140 final IVoiceInteractionSession session;
3142 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3143 if (lastResumedActivityTask != null
3144 && lastResumedActivityTask.voiceSession != null) {
3145 session = lastResumedActivityTask.voiceSession;
3147 session = mLastResumedActivity.voiceSession;
3150 if (session != null) {
3151 // We had been in a voice interaction session, but now focused has
3152 // move to something different. Just finish the session, we can't
3153 // return to it and retain the proper state and synchronization with
3154 // the voice interaction service.
3155 finishVoiceTask(session);
3160 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3161 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3162 mHandler.obtainMessage(
3163 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3165 mLastResumedActivity = r;
3167 mWindowManager.setFocusedApp(r.appToken, true);
3169 applyUpdateLockStateLocked(r);
3170 applyUpdateVrModeLocked(r);
3172 EventLogTags.writeAmSetResumedActivity(
3173 r == null ? -1 : r.userId,
3174 r == null ? "NULL" : r.shortComponentName,
3179 public void setFocusedStack(int stackId) {
3180 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3181 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3182 final long callingId = Binder.clearCallingIdentity();
3184 synchronized (this) {
3185 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3186 if (stack == null) {
3189 final ActivityRecord r = stack.topRunningActivityLocked();
3190 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3191 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3195 Binder.restoreCallingIdentity(callingId);
3200 public void setFocusedTask(int taskId) {
3201 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3202 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3203 final long callingId = Binder.clearCallingIdentity();
3205 synchronized (this) {
3206 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3210 final ActivityRecord r = task.topRunningActivityLocked();
3211 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3212 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3216 Binder.restoreCallingIdentity(callingId);
3220 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3222 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3223 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3224 mTaskChangeNotificationController.registerTaskStackListener(listener);
3228 * Unregister a task stack listener so that it stops receiving callbacks.
3231 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3232 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3233 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3237 public void notifyActivityDrawn(IBinder token) {
3238 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3239 synchronized (this) {
3240 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3242 r.getStack().notifyActivityDrawnLocked(r);
3247 final void applyUpdateLockStateLocked(ActivityRecord r) {
3248 // Modifications to the UpdateLock state are done on our handler, outside
3249 // the activity manager's locks. The new state is determined based on the
3250 // state *now* of the relevant activity record. The object is passed to
3251 // the handler solely for logging detail, not to be consulted/modified.
3252 final boolean nextState = r != null && r.immersive;
3253 mHandler.sendMessage(
3254 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3257 final void applyUpdateVrModeLocked(ActivityRecord r) {
3258 // VR apps are expected to run in a main display. If an app is turning on VR for
3259 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3260 // fullscreen stack before enabling VR Mode.
3261 // TODO: The goal of this code is to keep the VR app on the main display. When the
3262 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3263 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3264 // option would be a better choice here.
3265 if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3266 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3267 + " to main stack for VR");
3268 moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3270 mHandler.sendMessage(
3271 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3274 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3275 Message msg = Message.obtain();
3276 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3277 msg.obj = r.getTask().askedCompatMode ? null : r;
3278 mUiHandler.sendMessage(msg);
3281 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3282 final Configuration globalConfig = getGlobalConfiguration();
3283 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3284 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3285 final Message msg = Message.obtain();
3286 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3288 mUiHandler.sendMessage(msg);
3292 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3293 String what, Object obj, ProcessRecord srcApp) {
3294 app.lastActivityTime = now;
3296 if (app.activities.size() > 0) {
3297 // Don't want to touch dependent processes that are hosting activities.
3301 int lrui = mLruProcesses.lastIndexOf(app);
3303 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3304 + what + " " + obj + " from " + srcApp);
3308 if (lrui >= index) {
3309 // Don't want to cause this to move dependent processes *back* in the
3310 // list as if they were less frequently used.
3314 if (lrui >= mLruProcessActivityStart) {
3315 // Don't want to touch dependent processes that are hosting activities.
3319 mLruProcesses.remove(lrui);
3323 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3324 + " in LRU list: " + app);
3325 mLruProcesses.add(index, app);
3329 static void killProcessGroup(int uid, int pid) {
3330 if (sKillHandler != null) {
3331 sKillHandler.sendMessage(
3332 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3334 Slog.w(TAG, "Asked to kill process group before system bringup!");
3335 Process.killProcessGroup(uid, pid);
3339 final void removeLruProcessLocked(ProcessRecord app) {
3340 int lrui = mLruProcesses.lastIndexOf(app);
3343 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3344 killProcessQuiet(app.pid);
3345 killProcessGroup(app.uid, app.pid);
3347 if (lrui <= mLruProcessActivityStart) {
3348 mLruProcessActivityStart--;
3350 if (lrui <= mLruProcessServiceStart) {
3351 mLruProcessServiceStart--;
3353 mLruProcesses.remove(lrui);
3357 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3358 ProcessRecord client) {
3359 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3360 || app.treatLikeActivity;
3361 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3362 if (!activityChange && hasActivity) {
3363 // The process has activities, so we are only allowing activity-based adjustments
3364 // to move it. It should be kept in the front of the list with other
3365 // processes that have activities, and we don't want those to change their
3366 // order except due to activity operations.
3371 final long now = SystemClock.uptimeMillis();
3372 app.lastActivityTime = now;
3374 // First a quick reject: if the app is already at the position we will
3375 // put it, then there is nothing to do.
3377 final int N = mLruProcesses.size();
3378 if (N > 0 && mLruProcesses.get(N-1) == app) {
3379 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3383 if (mLruProcessServiceStart > 0
3384 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3385 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3390 int lrui = mLruProcesses.lastIndexOf(app);
3392 if (app.persistent && lrui >= 0) {
3393 // We don't care about the position of persistent processes, as long as
3394 // they are in the list.
3395 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3399 /* In progress: compute new position first, so we can avoid doing work
3400 if the process is not actually going to move. Not yet working.
3403 boolean inActivity = false, inService = false;
3405 // Process has activities, put it at the very tipsy-top.
3406 addIndex = mLruProcesses.size();
3407 nextIndex = mLruProcessServiceStart;
3409 } else if (hasService) {
3410 // Process has services, put it at the top of the service list.
3411 addIndex = mLruProcessActivityStart;
3412 nextIndex = mLruProcessServiceStart;
3416 // Process not otherwise of interest, it goes to the top of the non-service area.
3417 addIndex = mLruProcessServiceStart;
3418 if (client != null) {
3419 int clientIndex = mLruProcesses.lastIndexOf(client);
3420 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3422 if (clientIndex >= 0 && addIndex > clientIndex) {
3423 addIndex = clientIndex;
3426 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3429 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3430 + mLruProcessActivityStart + "): " + app);
3434 if (lrui < mLruProcessActivityStart) {
3435 mLruProcessActivityStart--;
3437 if (lrui < mLruProcessServiceStart) {
3438 mLruProcessServiceStart--;
3441 if (addIndex > lrui) {
3444 if (nextIndex > lrui) {
3448 mLruProcesses.remove(lrui);
3452 mLruProcesses.add(addIndex, app);
3454 mLruProcessActivityStart++;
3457 mLruProcessActivityStart++;
3463 final int N = mLruProcesses.size();
3464 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3465 // Process doesn't have activities, but has clients with
3466 // activities... move it up, but one below the top (the top
3467 // should always have a real activity).
3468 if (DEBUG_LRU) Slog.d(TAG_LRU,
3469 "Adding to second-top of LRU activity list: " + app);
3470 mLruProcesses.add(N - 1, app);
3471 // To keep it from spamming the LRU list (by making a bunch of clients),
3472 // we will push down any other entries owned by the app.
3473 final int uid = app.info.uid;
3474 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3475 ProcessRecord subProc = mLruProcesses.get(i);
3476 if (subProc.info.uid == uid) {
3477 // We want to push this one down the list. If the process after
3478 // it is for the same uid, however, don't do so, because we don't
3479 // want them internally to be re-ordered.
3480 if (mLruProcesses.get(i - 1).info.uid != uid) {
3481 if (DEBUG_LRU) Slog.d(TAG_LRU,
3482 "Pushing uid " + uid + " swapping at " + i + ": "
3483 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3484 ProcessRecord tmp = mLruProcesses.get(i);
3485 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3486 mLruProcesses.set(i - 1, tmp);
3490 // A gap, we can stop here.
3495 // Process has activities, put it at the very tipsy-top.
3496 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3497 mLruProcesses.add(app);
3499 nextIndex = mLruProcessServiceStart;
3500 } else if (hasService) {
3501 // Process has services, put it at the top of the service list.
3502 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3503 mLruProcesses.add(mLruProcessActivityStart, app);
3504 nextIndex = mLruProcessServiceStart;
3505 mLruProcessActivityStart++;
3507 // Process not otherwise of interest, it goes to the top of the non-service area.
3508 int index = mLruProcessServiceStart;
3509 if (client != null) {
3510 // If there is a client, don't allow the process to be moved up higher
3511 // in the list than that client.
3512 int clientIndex = mLruProcesses.lastIndexOf(client);
3513 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3514 + " when updating " + app);
3515 if (clientIndex <= lrui) {
3516 // Don't allow the client index restriction to push it down farther in the
3517 // list than it already is.
3520 if (clientIndex >= 0 && index > clientIndex) {
3521 index = clientIndex;
3524 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3525 mLruProcesses.add(index, app);
3526 nextIndex = index-1;
3527 mLruProcessActivityStart++;
3528 mLruProcessServiceStart++;
3531 // If the app is currently using a content provider or service,
3532 // bump those processes as well.
3533 for (int j=app.connections.size()-1; j>=0; j--) {
3534 ConnectionRecord cr = app.connections.valueAt(j);
3535 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3536 && cr.binding.service.app != null
3537 && cr.binding.service.app.lruSeq != mLruSeq
3538 && !cr.binding.service.app.persistent) {
3539 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3540 "service connection", cr, app);
3543 for (int j=app.conProviders.size()-1; j>=0; j--) {
3544 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3545 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3546 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3547 "provider reference", cpr, app);
3552 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3553 if (uid == SYSTEM_UID) {
3554 // The system gets to run in any process. If there are multiple
3555 // processes with the same uid, just pick the first (this
3556 // should never happen).
3557 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3558 if (procs == null) return null;
3559 final int procCount = procs.size();
3560 for (int i = 0; i < procCount; i++) {
3561 final int procUid = procs.keyAt(i);
3562 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3563 // Don't use an app process or different user process for system component.
3566 return procs.valueAt(i);
3569 ProcessRecord proc = mProcessNames.get(processName, uid);
3570 if (false && proc != null && !keepIfLarge
3571 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3572 && proc.lastCachedPss >= 4000) {
3573 // Turn this condition on to cause killing to happen regularly, for testing.
3574 if (proc.baseProcessTracker != null) {
3575 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3577 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3578 } else if (proc != null && !keepIfLarge
3579 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3580 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3581 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3582 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3583 if (proc.baseProcessTracker != null) {
3584 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3586 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3592 void notifyPackageUse(String packageName, int reason) {
3593 synchronized(this) {
3594 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3598 boolean isNextTransitionForward() {
3599 int transit = mWindowManager.getPendingAppTransition();
3600 return transit == TRANSIT_ACTIVITY_OPEN
3601 || transit == TRANSIT_TASK_OPEN
3602 || transit == TRANSIT_TASK_TO_FRONT;
3605 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3606 String processName, String abiOverride, int uid, Runnable crashHandler) {
3607 synchronized(this) {
3608 ApplicationInfo info = new ApplicationInfo();
3609 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3610 // For isolated processes, the former contains the parent's uid and the latter the
3611 // actual uid of the isolated process.
3612 // In the special case introduced by this method (which is, starting an isolated
3613 // process directly from the SystemServer without an actual parent app process) the
3614 // closest thing to a parent's uid is SYSTEM_UID.
3615 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3616 // the |isolated| logic in the ProcessRecord constructor.
3617 info.uid = SYSTEM_UID;
3618 info.processName = processName;
3619 info.className = entryPoint;
3620 info.packageName = "android";
3621 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3622 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3623 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3624 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3625 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3627 return proc != null ? proc.pid : 0;
3631 final ProcessRecord startProcessLocked(String processName,
3632 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3633 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3634 boolean isolated, boolean keepIfLarge) {
3635 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3636 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3637 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3638 null /* crashHandler */);
3641 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3642 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3643 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3644 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3645 long startTime = SystemClock.elapsedRealtime();
3648 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3649 checkTime(startTime, "startProcess: after getProcessRecord");
3651 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3652 // If we are in the background, then check to see if this process
3653 // is bad. If so, we will just silently fail.
3654 if (mAppErrors.isBadProcessLocked(info)) {
3655 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3656 + "/" + info.processName);
3660 // When the user is explicitly starting a process, then clear its
3661 // crash count so that we won't make it bad until they see at
3662 // least one crash dialog again, and make the process good again
3663 // if it had been bad.
3664 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3665 + "/" + info.processName);
3666 mAppErrors.resetProcessCrashTimeLocked(info);
3667 if (mAppErrors.isBadProcessLocked(info)) {
3668 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3669 UserHandle.getUserId(info.uid), info.uid,
3671 mAppErrors.clearBadProcessLocked(info);
3678 // If this is an isolated process, it can't re-use an existing process.
3682 // We don't have to do anything more if:
3683 // (1) There is an existing application record; and
3684 // (2) The caller doesn't think it is dead, OR there is no thread
3685 // object attached to it so we know it couldn't have crashed; and
3686 // (3) There is a pid assigned to it, so it is either starting or
3688 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3689 + " app=" + app + " knownToBeDead=" + knownToBeDead
3690 + " thread=" + (app != null ? app.thread : null)
3691 + " pid=" + (app != null ? app.pid : -1));
3692 if (app != null && app.pid > 0) {
3693 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3694 // We already have the app running, or are waiting for it to
3695 // come up (we have a pid but not yet its thread), so keep it.
3696 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3697 // If this is a new package in the process, add the package to the list
3698 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3699 checkTime(startTime, "startProcess: done, added package to proc");
3703 // An application record is attached to a previous process,
3705 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3706 checkTime(startTime, "startProcess: bad proc running, killing");
3707 killProcessGroup(app.uid, app.pid);
3708 handleAppDiedLocked(app, true, true);
3709 checkTime(startTime, "startProcess: done killing old proc");
3712 String hostingNameStr = hostingName != null
3713 ? hostingName.flattenToShortString() : null;
3716 checkTime(startTime, "startProcess: creating new process record");
3717 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3719 Slog.w(TAG, "Failed making new process record for "
3720 + processName + "/" + info.uid + " isolated=" + isolated);
3723 app.crashHandler = crashHandler;
3724 checkTime(startTime, "startProcess: done creating new process record");
3726 // If this is a new package in the process, add the package to the list
3727 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3728 checkTime(startTime, "startProcess: added package to existing proc");
3731 // If the system is not ready yet, then hold off on starting this
3732 // process until it is.
3733 if (!mProcessesReady
3734 && !isAllowedWhileBooting(info)
3735 && !allowWhileBooting) {
3736 if (!mProcessesOnHold.contains(app)) {
3737 mProcessesOnHold.add(app);
3739 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3740 "System not ready, putting on hold: " + app);
3741 checkTime(startTime, "startProcess: returning with proc on hold");
3745 checkTime(startTime, "startProcess: stepping in to startProcess");
3747 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3748 checkTime(startTime, "startProcess: done starting proc!");
3749 return (app.pid != 0) ? app : null;
3752 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3753 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3756 private final void startProcessLocked(ProcessRecord app,
3757 String hostingType, String hostingNameStr) {
3758 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3759 null /* entryPoint */, null /* entryPointArgs */);
3762 private final void startProcessLocked(ProcessRecord app, String hostingType,
3763 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3764 long startTime = SystemClock.elapsedRealtime();
3765 if (app.pid > 0 && app.pid != MY_PID) {
3766 checkTime(startTime, "startProcess: removing from pids map");
3767 synchronized (mPidsSelfLocked) {
3768 mPidsSelfLocked.remove(app.pid);
3769 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3771 checkTime(startTime, "startProcess: done removing from pids map");
3775 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3776 "startProcessLocked removing on hold: " + app);
3777 mProcessesOnHold.remove(app);
3779 checkTime(startTime, "startProcess: starting to update cpu stats");
3781 checkTime(startTime, "startProcess: done updating cpu stats");
3785 final int userId = UserHandle.getUserId(app.uid);
3786 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3787 } catch (RemoteException e) {
3788 throw e.rethrowAsRuntimeException();
3793 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3794 if (!app.isolated) {
3795 int[] permGids = null;
3797 checkTime(startTime, "startProcess: getting gids from package manager");
3798 final IPackageManager pm = AppGlobals.getPackageManager();
3799 permGids = pm.getPackageGids(app.info.packageName,
3800 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3801 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3802 StorageManagerInternal.class);
3803 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3804 app.info.packageName);
3805 } catch (RemoteException e) {
3806 throw e.rethrowAsRuntimeException();
3810 * Add shared application and profile GIDs so applications can share some
3811 * resources like shared libraries and access user-wide resources
3813 if (ArrayUtils.isEmpty(permGids)) {
3816 gids = new int[permGids.length + 3];
3817 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3819 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3820 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3821 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3823 // Replace any invalid GIDs
3824 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
3825 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
3827 checkTime(startTime, "startProcess: building args");
3828 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3829 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3830 && mTopComponent != null
3831 && app.processName.equals(mTopComponent.getPackageName())) {
3834 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3835 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3839 int runtimeFlags = 0;
3840 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3841 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3842 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3843 // Also turn on CheckJNI for debuggable apps. It's quite
3844 // awkward to turn on otherwise.
3845 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3847 // Run the app in safe mode if its manifest requests so or the
3848 // system is booted in safe mode.
3849 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3850 mSafeMode == true) {
3851 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3853 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3854 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3856 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3857 if ("true".equals(genDebugInfoProperty)) {
3858 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3860 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3861 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3863 if ("1".equals(SystemProperties.get("debug.assert"))) {
3864 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3866 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3867 // Enable all debug flags required by the native debugger.
3868 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3869 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3870 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3871 mNativeDebuggingApp = null;
3874 if (app.info.isPrivilegedApp() &&
3875 !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
3876 runtimeFlags |= Zygote.DISABLE_VERIFIER;
3877 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
3880 String invokeWith = null;
3881 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3882 // Debuggable apps may include a wrapper script with their library directory.
3883 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3884 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3886 if (new File(wrapperFileName).exists()) {
3887 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3890 StrictMode.setThreadPolicy(oldPolicy);
3894 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3895 if (requiredAbi == null) {
3896 requiredAbi = Build.SUPPORTED_ABIS[0];
3899 String instructionSet = null;
3900 if (app.info.primaryCpuAbi != null) {
3901 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3905 app.requiredAbi = requiredAbi;
3906 app.instructionSet = instructionSet;
3908 // the per-user SELinux context must be set
3909 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3910 Slog.wtf(TAG, "SELinux tag not defined",
3911 new IllegalStateException("SELinux tag not defined for "
3912 + app.info.packageName + " (uid " + app.uid + ")"));
3914 final String seInfo = app.info.seInfo
3915 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3916 // Start the process. It will either succeed and return a result containing
3917 // the PID of the new process, or else throw a RuntimeException.
3918 boolean isActivityProcess = (entryPoint == null);
3919 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3920 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3922 checkTime(startTime, "startProcess: asking zygote to start proc");
3923 ProcessStartResult startResult;
3924 if (hostingType.equals("webview_service")) {
3925 startResult = startWebView(entryPoint,
3926 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3927 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3928 app.info.dataDir, null, entryPointArgs);
3930 startResult = Process.start(entryPoint,
3931 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3932 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3933 app.info.dataDir, invokeWith, entryPointArgs);
3935 checkTime(startTime, "startProcess: returned from zygote!");
3936 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3938 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3939 checkTime(startTime, "startProcess: done updating battery stats");
3941 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3942 UserHandle.getUserId(uid), startResult.pid, uid,
3943 app.processName, hostingType,
3944 hostingNameStr != null ? hostingNameStr : "");
3947 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3948 seInfo, app.info.sourceDir, startResult.pid);
3949 } catch (RemoteException ex) {
3953 if (app.persistent) {
3954 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3957 checkTime(startTime, "startProcess: building log message");
3958 StringBuilder buf = mStringBuilder;
3960 buf.append("Start proc ");
3961 buf.append(startResult.pid);
3963 buf.append(app.processName);
3965 UserHandle.formatUid(buf, uid);
3966 if (!isActivityProcess) {
3968 buf.append(entryPoint);
3971 buf.append(" for ");
3972 buf.append(hostingType);
3973 if (hostingNameStr != null) {
3975 buf.append(hostingNameStr);
3977 Slog.i(TAG, buf.toString());
3978 app.setPid(startResult.pid);
3979 app.usingWrapper = startResult.usingWrapper;
3980 app.removed = false;
3982 app.killedByAm = false;
3983 checkTime(startTime, "startProcess: starting to update pids map");
3984 ProcessRecord oldApp;
3985 synchronized (mPidsSelfLocked) {
3986 oldApp = mPidsSelfLocked.get(startResult.pid);
3988 // If there is already an app occupying that pid that hasn't been cleaned up
3989 if (oldApp != null && !app.isolated) {
3990 // Clean up anything relating to this pid first
3991 Slog.w(TAG, "Reusing pid " + startResult.pid
3992 + " while app is still mapped to it");
3993 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3994 true /*replacingPid*/);
3996 synchronized (mPidsSelfLocked) {
3997 this.mPidsSelfLocked.put(startResult.pid, app);
3998 if (isActivityProcess) {
3999 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4001 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4002 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4005 checkTime(startTime, "startProcess: done updating pids map");
4006 } catch (RuntimeException e) {
4007 Slog.e(TAG, "Failure starting process " + app.processName, e);
4009 // Something went very wrong while trying to start this process; one
4010 // common case is when the package is frozen due to an active
4011 // upgrade. To recover, clean up any active bookkeeping related to
4012 // starting this process. (We already invoked this method once when
4013 // the package was initially frozen through KILL_APPLICATION_MSG, so
4014 // it doesn't hurt to use it again.)
4015 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4016 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4020 void updateUsageStats(ActivityRecord component, boolean resumed) {
4021 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4022 "updateUsageStats: comp=" + component + "res=" + resumed);
4023 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4025 if (mUsageStatsService != null) {
4026 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4027 UsageEvents.Event.MOVE_TO_FOREGROUND);
4029 synchronized (stats) {
4030 stats.noteActivityResumedLocked(component.app.uid);
4033 if (mUsageStatsService != null) {
4034 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4035 UsageEvents.Event.MOVE_TO_BACKGROUND);
4037 synchronized (stats) {
4038 stats.noteActivityPausedLocked(component.app.uid);
4043 Intent getHomeIntent() {
4044 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4045 intent.setComponent(mTopComponent);
4046 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4047 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4048 intent.addCategory(Intent.CATEGORY_HOME);
4053 boolean startHomeActivityLocked(int userId, String reason) {
4054 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4055 && mTopAction == null) {
4056 // We are running in factory test mode, but unable to find
4057 // the factory test app, so just sit around displaying the
4058 // error message and don't try to start anything.
4061 Intent intent = getHomeIntent();
4062 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4063 if (aInfo != null) {
4064 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4065 // Don't do this if the home app is currently being
4067 aInfo = new ActivityInfo(aInfo);
4068 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4069 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4070 aInfo.applicationInfo.uid, true);
4071 if (app == null || app.instr == null) {
4072 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4073 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4074 // For ANR debugging to verify if the user activity is the one that actually
4076 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4077 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4080 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4086 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4087 ActivityInfo ai = null;
4088 ComponentName comp = intent.getComponent();
4092 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4094 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4096 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4100 ai = info.activityInfo;
4103 } catch (RemoteException e) {
4111 * Starts the "new version setup screen" if appropriate.
4113 void startSetupActivityLocked() {
4114 // Only do this once per boot.
4115 if (mCheckedForSetup) {
4119 // We will show this screen if the current one is a different
4120 // version than the last one shown, and we are not running in
4121 // low-level factory test mode.
4122 final ContentResolver resolver = mContext.getContentResolver();
4123 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4124 Settings.Global.getInt(resolver,
4125 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4126 mCheckedForSetup = true;
4128 // See if we should be showing the platform update setup UI.
4129 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4130 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4131 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4132 if (!ris.isEmpty()) {
4133 final ResolveInfo ri = ris.get(0);
4134 String vers = ri.activityInfo.metaData != null
4135 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4137 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4138 vers = ri.activityInfo.applicationInfo.metaData.getString(
4139 Intent.METADATA_SETUP_VERSION);
4141 String lastVers = Settings.Secure.getString(
4142 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4143 if (vers != null && !vers.equals(lastVers)) {
4144 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4145 intent.setComponent(new ComponentName(
4146 ri.activityInfo.packageName, ri.activityInfo.name));
4147 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4148 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4149 null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4155 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4156 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4159 void enforceNotIsolatedCaller(String caller) {
4160 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4161 throw new SecurityException("Isolated process not allowed to call " + caller);
4165 void enforceShellRestriction(String restriction, int userHandle) {
4166 if (Binder.getCallingUid() == SHELL_UID) {
4167 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4168 throw new SecurityException("Shell does not have permission to access user "
4175 public int getFrontActivityScreenCompatMode() {
4176 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4177 synchronized (this) {
4178 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4183 public void setFrontActivityScreenCompatMode(int mode) {
4184 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4185 "setFrontActivityScreenCompatMode");
4186 synchronized (this) {
4187 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4192 public int getPackageScreenCompatMode(String packageName) {
4193 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4194 synchronized (this) {
4195 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4200 public void setPackageScreenCompatMode(String packageName, int mode) {
4201 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4202 "setPackageScreenCompatMode");
4203 synchronized (this) {
4204 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4209 public boolean getPackageAskScreenCompat(String packageName) {
4210 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4211 synchronized (this) {
4212 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4217 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4218 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4219 "setPackageAskScreenCompat");
4220 synchronized (this) {
4221 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4225 private boolean hasUsageStatsPermission(String callingPackage) {
4226 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4227 Binder.getCallingUid(), callingPackage);
4228 if (mode == AppOpsManager.MODE_DEFAULT) {
4229 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4230 == PackageManager.PERMISSION_GRANTED;
4232 return mode == AppOpsManager.MODE_ALLOWED;
4236 public int getPackageProcessState(String packageName, String callingPackage) {
4237 if (!hasUsageStatsPermission(callingPackage)) {
4238 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4239 "getPackageProcessState");
4242 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4243 synchronized (this) {
4244 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4245 final ProcessRecord proc = mLruProcesses.get(i);
4246 if (procState > proc.setProcState) {
4247 if (proc.pkgList.containsKey(packageName) ||
4248 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4249 procState = proc.setProcState;
4258 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4259 throws RemoteException {
4260 synchronized (this) {
4261 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4263 throw new IllegalArgumentException("Unknown process: " + process);
4265 if (app.thread == null) {
4266 throw new IllegalArgumentException("Process has no app thread");
4268 if (app.trimMemoryLevel >= level) {
4269 throw new IllegalArgumentException(
4270 "Unable to set a higher trim level than current level");
4272 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4273 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4274 throw new IllegalArgumentException("Unable to set a background trim level "
4275 + "on a foreground process");
4277 app.thread.scheduleTrimMemory(level);
4278 app.trimMemoryLevel = level;
4283 private void dispatchProcessesChanged() {
4285 synchronized (this) {
4286 N = mPendingProcessChanges.size();
4287 if (mActiveProcessChanges.length < N) {
4288 mActiveProcessChanges = new ProcessChangeItem[N];
4290 mPendingProcessChanges.toArray(mActiveProcessChanges);
4291 mPendingProcessChanges.clear();
4292 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4293 "*** Delivering " + N + " process changes");
4296 int i = mProcessObservers.beginBroadcast();
4299 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4300 if (observer != null) {
4302 for (int j=0; j<N; j++) {
4303 ProcessChangeItem item = mActiveProcessChanges[j];
4304 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4305 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4306 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4307 + item.uid + ": " + item.foregroundActivities);
4308 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4309 item.foregroundActivities);
4312 } catch (RemoteException e) {
4316 mProcessObservers.finishBroadcast();
4318 synchronized (this) {
4319 for (int j=0; j<N; j++) {
4320 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4325 private void dispatchProcessDied(int pid, int uid) {
4326 int i = mProcessObservers.beginBroadcast();
4329 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4330 if (observer != null) {
4332 observer.onProcessDied(pid, uid);
4333 } catch (RemoteException e) {
4337 mProcessObservers.finishBroadcast();
4341 void dispatchUidsChanged() {
4343 synchronized (this) {
4344 N = mPendingUidChanges.size();
4345 if (mActiveUidChanges.length < N) {
4346 mActiveUidChanges = new UidRecord.ChangeItem[N];
4348 for (int i=0; i<N; i++) {
4349 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4350 mActiveUidChanges[i] = change;
4351 if (change.uidRecord != null) {
4352 change.uidRecord.pendingChange = null;
4353 change.uidRecord = null;
4356 mPendingUidChanges.clear();
4357 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4358 "*** Delivering " + N + " uid changes");
4361 int i = mUidObservers.beginBroadcast();
4364 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4365 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4367 mUidObservers.finishBroadcast();
4369 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4370 for (int j = 0; j < N; ++j) {
4371 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4372 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4373 mValidateUids.remove(item.uid);
4375 UidRecord validateUid = mValidateUids.get(item.uid);
4376 if (validateUid == null) {
4377 validateUid = new UidRecord(item.uid);
4378 mValidateUids.put(item.uid, validateUid);
4380 if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4381 validateUid.idle = true;
4382 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4383 validateUid.idle = false;
4385 validateUid.curProcState = validateUid.setProcState = item.processState;
4386 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4391 synchronized (this) {
4392 for (int j = 0; j < N; j++) {
4393 mAvailUidChanges.add(mActiveUidChanges[j]);
4398 private void dispatchUidsChangedForObserver(IUidObserver observer,
4399 UidObserverRegistration reg, int changesSize) {
4400 if (observer == null) {
4404 for (int j = 0; j < changesSize; j++) {
4405 UidRecord.ChangeItem item = mActiveUidChanges[j];
4406 final int change = item.change;
4407 if (change == UidRecord.CHANGE_PROCSTATE &&
4408 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4409 // No-op common case: no significant change, the observer is not
4410 // interested in all proc state changes.
4413 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4414 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4415 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4416 "UID idle uid=" + item.uid);
4417 observer.onUidIdle(item.uid, item.ephemeral);
4419 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4420 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4421 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422 "UID active uid=" + item.uid);
4423 observer.onUidActive(item.uid);
4426 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4427 if ((change & UidRecord.CHANGE_CACHED) != 0) {
4428 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4429 "UID cached uid=" + item.uid);
4430 observer.onUidCachedChanged(item.uid, true);
4431 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4432 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4433 "UID active uid=" + item.uid);
4434 observer.onUidCachedChanged(item.uid, false);
4437 if ((change & UidRecord.CHANGE_GONE) != 0) {
4438 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4439 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4440 "UID gone uid=" + item.uid);
4441 observer.onUidGone(item.uid, item.ephemeral);
4443 if (reg.lastProcStates != null) {
4444 reg.lastProcStates.delete(item.uid);
4447 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4448 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4449 "UID CHANGED uid=" + item.uid
4450 + ": " + item.processState);
4451 boolean doReport = true;
4452 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4453 final int lastState = reg.lastProcStates.get(item.uid,
4454 ActivityManager.PROCESS_STATE_UNKNOWN);
4455 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4456 final boolean lastAboveCut = lastState <= reg.cutpoint;
4457 final boolean newAboveCut = item.processState <= reg.cutpoint;
4458 doReport = lastAboveCut != newAboveCut;
4460 doReport = item.processState
4461 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4465 if (reg.lastProcStates != null) {
4466 reg.lastProcStates.put(item.uid, item.processState);
4468 observer.onUidStateChanged(item.uid, item.processState,
4474 } catch (RemoteException e) {
4478 void dispatchOomAdjObserver(String msg) {
4479 OomAdjObserver observer;
4480 synchronized (this) {
4481 observer = mCurOomAdjObserver;
4484 if (observer != null) {
4485 observer.onOomAdjMessage(msg);
4489 void setOomAdjObserver(int uid, OomAdjObserver observer) {
4490 synchronized (this) {
4491 mCurOomAdjUid = uid;
4492 mCurOomAdjObserver = observer;
4496 void clearOomAdjObserver() {
4497 synchronized (this) {
4499 mCurOomAdjObserver = null;
4503 void reportOomAdjMessageLocked(String tag, String msg) {
4505 if (mCurOomAdjObserver != null) {
4506 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4511 public final int startActivity(IApplicationThread caller, String callingPackage,
4512 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4513 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4514 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4515 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4516 UserHandle.getCallingUserId());
4520 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4521 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4522 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4523 enforceNotIsolatedCaller("startActivity");
4524 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4525 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4526 // TODO: Switch to user app stacks here.
4527 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4528 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4529 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4533 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4534 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4535 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4538 // This is very dangerous -- it allows you to perform a start activity (including
4539 // permission grants) as any app that may launch one of your own activities. So
4540 // we will only allow this to be done from activities that are part of the core framework,
4541 // and then only when they are running as the system.
4542 final ActivityRecord sourceRecord;
4543 final int targetUid;
4544 final String targetPackage;
4545 synchronized (this) {
4546 if (resultTo == null) {
4547 throw new SecurityException("Must be called from an activity");
4549 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4550 if (sourceRecord == null) {
4551 throw new SecurityException("Called with bad activity token: " + resultTo);
4553 if (!sourceRecord.info.packageName.equals("android")) {
4554 throw new SecurityException(
4555 "Must be called from an activity that is declared in the android package");
4557 if (sourceRecord.app == null) {
4558 throw new SecurityException("Called without a process attached to activity");
4560 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4561 // This is still okay, as long as this activity is running under the
4562 // uid of the original calling activity.
4563 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4564 throw new SecurityException(
4565 "Calling activity in uid " + sourceRecord.app.uid
4566 + " must be system uid or original calling uid "
4567 + sourceRecord.launchedFromUid);
4570 if (ignoreTargetSecurity) {
4571 if (intent.getComponent() == null) {
4572 throw new SecurityException(
4573 "Component must be specified with ignoreTargetSecurity");
4575 if (intent.getSelector() != null) {
4576 throw new SecurityException(
4577 "Selector not allowed with ignoreTargetSecurity");
4580 targetUid = sourceRecord.launchedFromUid;
4581 targetPackage = sourceRecord.launchedFromPackage;
4584 if (userId == UserHandle.USER_NULL) {
4585 userId = UserHandle.getUserId(sourceRecord.app.uid);
4588 // TODO: Switch to user app stacks here.
4590 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4591 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4592 null, null, bOptions, ignoreTargetSecurity, userId, null,
4593 "startActivityAsCaller");
4595 } catch (SecurityException e) {
4596 // XXX need to figure out how to propagate to original app.
4597 // A SecurityException here is generally actually a fault of the original
4598 // calling activity (such as a fairly granting permissions), so propagate it
4601 StringBuilder msg = new StringBuilder();
4602 msg.append("While launching");
4603 msg.append(intent.toString());
4605 msg.append(e.getMessage());
4612 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4613 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4614 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4615 enforceNotIsolatedCaller("startActivityAndWait");
4616 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4617 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4618 WaitResult res = new WaitResult();
4619 // TODO: Switch to user app stacks here.
4620 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4621 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4622 bOptions, false, userId, null, "startActivityAndWait");
4627 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4628 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4629 int startFlags, Configuration config, Bundle bOptions, int userId) {
4630 enforceNotIsolatedCaller("startActivityWithConfig");
4631 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4632 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4633 // TODO: Switch to user app stacks here.
4634 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4635 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4636 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4641 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4642 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4643 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4644 throws TransactionTooLargeException {
4645 enforceNotIsolatedCaller("startActivityIntentSender");
4646 // Refuse possible leaked file descriptors
4647 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4648 throw new IllegalArgumentException("File descriptors passed in Intent");
4651 if (!(target instanceof PendingIntentRecord)) {
4652 throw new IllegalArgumentException("Bad PendingIntent object");
4655 PendingIntentRecord pir = (PendingIntentRecord)target;
4657 synchronized (this) {
4658 // If this is coming from the currently resumed activity, it is
4659 // effectively saying that app switches are allowed at this point.
4660 final ActivityStack stack = getFocusedStack();
4661 if (stack.mResumedActivity != null &&
4662 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4663 mAppSwitchesAllowedTime = 0;
4666 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4667 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4672 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4673 Intent intent, String resolvedType, IVoiceInteractionSession session,
4674 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4675 Bundle bOptions, int userId) {
4676 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4677 != PackageManager.PERMISSION_GRANTED) {
4678 String msg = "Permission Denial: startVoiceActivity() from pid="
4679 + Binder.getCallingPid()
4680 + ", uid=" + Binder.getCallingUid()
4681 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4683 throw new SecurityException(msg);
4685 if (session == null || interactor == null) {
4686 throw new NullPointerException("null session or interactor");
4688 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4689 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4690 // TODO: Switch to user app stacks here.
4691 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4692 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4693 null, bOptions, false, userId, null, "startVoiceActivity");
4697 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4698 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4699 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4700 != PackageManager.PERMISSION_GRANTED) {
4701 final String msg = "Permission Denial: startAssistantActivity() from pid="
4702 + Binder.getCallingPid()
4703 + ", uid=" + Binder.getCallingUid()
4704 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4706 throw new SecurityException(msg);
4708 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4709 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4710 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4711 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4712 userId, null, "startAssistantActivity");
4716 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4717 throws RemoteException {
4718 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4719 synchronized (this) {
4720 ActivityRecord activity = getFocusedStack().topActivity();
4721 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4722 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4724 if (mRunningVoice != null || activity.getTask().voiceSession != null
4725 || activity.voiceSession != null) {
4726 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4729 if (activity.pendingVoiceInteractionStart) {
4730 Slog.w(TAG, "Pending start of voice interaction already.");
4733 activity.pendingVoiceInteractionStart = true;
4735 LocalServices.getService(VoiceInteractionManagerInternal.class)
4736 .startLocalVoiceInteraction(callingActivity, options);
4740 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4741 LocalServices.getService(VoiceInteractionManagerInternal.class)
4742 .stopLocalVoiceInteraction(callingActivity);
4746 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4747 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4748 .supportsLocalVoiceInteraction();
4751 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4752 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4753 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4754 if (activityToCallback == null) return;
4755 activityToCallback.setVoiceSessionLocked(voiceSession);
4757 // Inform the activity
4759 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4761 long token = Binder.clearCallingIdentity();
4763 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4765 Binder.restoreCallingIdentity(token);
4767 // TODO: VI Should we cache the activity so that it's easier to find later
4768 // rather than scan through all the stacks and activities?
4769 } catch (RemoteException re) {
4770 activityToCallback.clearVoiceSessionLocked();
4771 // TODO: VI Should this terminate the voice session?
4776 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4777 synchronized (this) {
4778 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4780 mVoiceWakeLock.acquire();
4782 mVoiceWakeLock.release();
4789 public boolean startNextMatchingActivity(IBinder callingActivity,
4790 Intent intent, Bundle bOptions) {
4791 // Refuse possible leaked file descriptors
4792 if (intent != null && intent.hasFileDescriptors() == true) {
4793 throw new IllegalArgumentException("File descriptors passed in Intent");
4795 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4797 synchronized (this) {
4798 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4800 ActivityOptions.abort(options);
4803 if (r.app == null || r.app.thread == null) {
4804 // The caller is not running... d'oh!
4805 ActivityOptions.abort(options);
4808 intent = new Intent(intent);
4809 // The caller is not allowed to change the data.
4810 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4811 // And we are resetting to find the next component...
4812 intent.setComponent(null);
4814 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4816 ActivityInfo aInfo = null;
4818 List<ResolveInfo> resolves =
4819 AppGlobals.getPackageManager().queryIntentActivities(
4820 intent, r.resolvedType,
4821 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4822 UserHandle.getCallingUserId()).getList();
4824 // Look for the original activity in the list...
4825 final int N = resolves != null ? resolves.size() : 0;
4826 for (int i=0; i<N; i++) {
4827 ResolveInfo rInfo = resolves.get(i);
4828 if (rInfo.activityInfo.packageName.equals(r.packageName)
4829 && rInfo.activityInfo.name.equals(r.info.name)) {
4830 // We found the current one... the next matching is
4834 aInfo = resolves.get(i).activityInfo;
4837 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4838 + "/" + r.info.name);
4839 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4840 ? "null" : aInfo.packageName + "/" + aInfo.name));
4845 } catch (RemoteException e) {
4848 if (aInfo == null) {
4849 // Nobody who is next!
4850 ActivityOptions.abort(options);
4851 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4855 intent.setComponent(new ComponentName(
4856 aInfo.applicationInfo.packageName, aInfo.name));
4857 intent.setFlags(intent.getFlags()&~(
4858 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4859 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4860 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4861 Intent.FLAG_ACTIVITY_NEW_TASK));
4863 // Okay now we need to start the new activity, replacing the
4864 // currently running activity. This is a little tricky because
4865 // we want to start the new one as if the current one is finished,
4866 // but not finish the current one first so that there is no flicker.
4868 final boolean wasFinishing = r.finishing;
4871 // Propagate reply information over to the new activity.
4872 final ActivityRecord resultTo = r.resultTo;
4873 final String resultWho = r.resultWho;
4874 final int requestCode = r.requestCode;
4876 if (resultTo != null) {
4877 resultTo.removeResultsLocked(r, resultWho, requestCode);
4880 final long origId = Binder.clearCallingIdentity();
4881 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4882 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4883 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4884 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4885 false, false, null, null, "startNextMatchingActivity");
4886 Binder.restoreCallingIdentity(origId);
4888 r.finishing = wasFinishing;
4889 if (res != ActivityManager.START_SUCCESS) {
4897 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4898 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4899 String msg = "Permission Denial: startActivityFromRecents called without " +
4900 START_TASKS_FROM_RECENTS;
4902 throw new SecurityException(msg);
4904 final long origId = Binder.clearCallingIdentity();
4906 synchronized (this) {
4907 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4910 Binder.restoreCallingIdentity(origId);
4914 final int startActivityInPackage(int uid, String callingPackage,
4915 Intent intent, String resolvedType, IBinder resultTo,
4916 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4917 TaskRecord inTask, String reason) {
4919 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4920 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4922 // TODO: Switch to user app stacks here.
4923 return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4924 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4925 null, null, null, bOptions, false, userId, inTask, reason);
4929 public final int startActivities(IApplicationThread caller, String callingPackage,
4930 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4932 final String reason = "startActivities";
4933 enforceNotIsolatedCaller(reason);
4934 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4935 userId, false, ALLOW_FULL_ONLY, reason, null);
4936 // TODO: Switch to user app stacks here.
4937 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4938 resolvedTypes, resultTo, bOptions, userId, reason);
4942 final int startActivitiesInPackage(int uid, String callingPackage,
4943 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4944 Bundle bOptions, int userId) {
4946 final String reason = "startActivityInPackage";
4947 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4948 userId, false, ALLOW_FULL_ONLY, reason, null);
4949 // TODO: Switch to user app stacks here.
4950 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4951 resultTo, bOptions, userId, reason);
4956 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4957 synchronized (this) {
4958 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4962 r.reportFullyDrawnLocked(restoredFromBundle);
4967 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4968 synchronized (this) {
4969 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4973 final long origId = Binder.clearCallingIdentity();
4975 r.setRequestedOrientation(requestedOrientation);
4977 Binder.restoreCallingIdentity(origId);
4983 public int getRequestedOrientation(IBinder token) {
4984 synchronized (this) {
4985 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4987 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4989 return r.getRequestedOrientation();
4994 public final void requestActivityRelaunch(IBinder token) {
4995 synchronized(this) {
4996 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5000 final long origId = Binder.clearCallingIdentity();
5002 r.forceNewConfig = true;
5003 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5004 true /* preserveWindow */);
5006 Binder.restoreCallingIdentity(origId);
5012 * This is the internal entry point for handling Activity.finish().
5014 * @param token The Binder token referencing the Activity we want to finish.
5015 * @param resultCode Result code, if any, from this Activity.
5016 * @param resultData Result data (Intent), if any, from this Activity.
5017 * @param finishTask Whether to finish the task associated with this Activity.
5019 * @return Returns true if the activity successfully finished, or false if it is still running.
5022 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5024 // Refuse possible leaked file descriptors
5025 if (resultData != null && resultData.hasFileDescriptors() == true) {
5026 throw new IllegalArgumentException("File descriptors passed in Intent");
5029 synchronized(this) {
5030 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5034 // Keep track of the root activity of the task before we finish it
5035 TaskRecord tr = r.getTask();
5036 ActivityRecord rootR = tr.getRootActivity();
5037 if (rootR == null) {
5038 Slog.w(TAG, "Finishing task with all activities already finished");
5040 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5042 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5043 mStackSupervisor.isLastLockedTask(tr)) {
5044 Slog.i(TAG, "Not finishing task in lock task mode");
5045 mStackSupervisor.showLockTaskToast();
5048 if (mController != null) {
5049 // Find the first activity that is not finishing.
5050 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5052 // ask watcher if this is allowed
5053 boolean resumeOK = true;
5055 resumeOK = mController.activityResuming(next.packageName);
5056 } catch (RemoteException e) {
5058 Watchdog.getInstance().setActivityController(null);
5062 Slog.i(TAG, "Not finishing activity because controller resumed");
5067 final long origId = Binder.clearCallingIdentity();
5070 final boolean finishWithRootActivity =
5071 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5072 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5073 || (finishWithRootActivity && r == rootR)) {
5074 // If requested, remove the task that is associated to this activity only if it
5075 // was the root activity in the task. The result code and data is ignored
5076 // because we don't support returning them across task boundaries. Also, to
5077 // keep backwards compatibility we remove the task from recents when finishing
5078 // task with root activity.
5079 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5081 Slog.i(TAG, "Removing task failed to finish activity");
5084 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5085 resultData, "app-request", true);
5087 Slog.i(TAG, "Failed to finish by app-request");
5092 Binder.restoreCallingIdentity(origId);
5098 public final void finishHeavyWeightApp() {
5099 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5100 != PackageManager.PERMISSION_GRANTED) {
5101 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5102 + Binder.getCallingPid()
5103 + ", uid=" + Binder.getCallingUid()
5104 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5106 throw new SecurityException(msg);
5109 synchronized(this) {
5110 if (mHeavyWeightProcess == null) {
5114 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5115 for (int i = 0; i < activities.size(); i++) {
5116 ActivityRecord r = activities.get(i);
5117 if (!r.finishing && r.isInStackLocked()) {
5118 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5119 null, "finish-heavy", true);
5123 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5124 mHeavyWeightProcess.userId, 0));
5125 mHeavyWeightProcess = null;
5130 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5132 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5133 != PackageManager.PERMISSION_GRANTED) {
5134 String msg = "Permission Denial: crashApplication() from pid="
5135 + Binder.getCallingPid()
5136 + ", uid=" + Binder.getCallingUid()
5137 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5139 throw new SecurityException(msg);
5142 synchronized(this) {
5143 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5148 public final void finishSubActivity(IBinder token, String resultWho,
5150 synchronized(this) {
5151 final long origId = Binder.clearCallingIdentity();
5152 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5154 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5156 Binder.restoreCallingIdentity(origId);
5161 public boolean finishActivityAffinity(IBinder token) {
5162 synchronized(this) {
5163 final long origId = Binder.clearCallingIdentity();
5165 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5170 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5172 final TaskRecord task = r.getTask();
5173 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5174 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5175 mStackSupervisor.showLockTaskToast();
5178 return task.getStack().finishActivityAffinityLocked(r);
5180 Binder.restoreCallingIdentity(origId);
5186 public void finishVoiceTask(IVoiceInteractionSession session) {
5187 synchronized (this) {
5188 final long origId = Binder.clearCallingIdentity();
5190 // TODO: VI Consider treating local voice interactions and voice tasks
5192 mStackSupervisor.finishVoiceTask(session);
5194 Binder.restoreCallingIdentity(origId);
5201 public boolean releaseActivityInstance(IBinder token) {
5202 synchronized(this) {
5203 final long origId = Binder.clearCallingIdentity();
5205 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5209 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5211 Binder.restoreCallingIdentity(origId);
5217 public void releaseSomeActivities(IApplicationThread appInt) {
5218 synchronized(this) {
5219 final long origId = Binder.clearCallingIdentity();
5221 ProcessRecord app = getRecordForAppLocked(appInt);
5222 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5224 Binder.restoreCallingIdentity(origId);
5230 public boolean willActivityBeVisible(IBinder token) {
5231 synchronized(this) {
5232 ActivityStack stack = ActivityRecord.getStackLocked(token);
5233 if (stack != null) {
5234 return stack.willActivityBeVisibleLocked(token);
5241 public void overridePendingTransition(IBinder token, String packageName,
5242 int enterAnim, int exitAnim) {
5243 synchronized(this) {
5244 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5249 final long origId = Binder.clearCallingIdentity();
5251 if (self.state == ActivityState.RESUMED
5252 || self.state == ActivityState.PAUSING) {
5253 mWindowManager.overridePendingAppTransition(packageName,
5254 enterAnim, exitAnim, null);
5257 Binder.restoreCallingIdentity(origId);
5262 * Main function for removing an existing process from the activity manager
5263 * as a result of that process going away. Clears out all connections
5266 private final void handleAppDiedLocked(ProcessRecord app,
5267 boolean restarting, boolean allowRestart) {
5269 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5270 false /*replacingPid*/);
5271 if (!kept && !restarting) {
5272 removeLruProcessLocked(app);
5274 ProcessList.remove(pid);
5278 if (mProfileProc == app) {
5279 clearProfilerLocked();
5282 // Remove this application's activities from active lists.
5283 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5285 app.activities.clear();
5287 if (app.instr != null) {
5288 Slog.w(TAG, "Crash of app " + app.processName
5289 + " running instrumentation " + app.instr.mClass);
5290 Bundle info = new Bundle();
5291 info.putString("shortMsg", "Process crashed.");
5292 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5295 mWindowManager.deferSurfaceLayout();
5297 if (!restarting && hasVisibleActivities
5298 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5299 // If there was nothing to resume, and we are not already restarting this process, but
5300 // there is a visible activity that is hosted by the process... then make sure all
5301 // visible activities are running, taking care of restarting this process.
5302 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5305 mWindowManager.continueSurfaceLayout();
5309 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5310 final IBinder threadBinder = thread.asBinder();
5311 // Find the application record.
5312 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5313 final ProcessRecord rec = mLruProcesses.get(i);
5314 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5321 final ProcessRecord getRecordForAppLocked(
5322 IApplicationThread thread) {
5323 if (thread == null) {
5327 int appIndex = getLRURecordIndexForAppLocked(thread);
5328 if (appIndex >= 0) {
5329 return mLruProcesses.get(appIndex);
5332 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5333 // double-check that.
5334 final IBinder threadBinder = thread.asBinder();
5335 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5336 for (int i = pmap.size()-1; i >= 0; i--) {
5337 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5338 for (int j = procs.size()-1; j >= 0; j--) {
5339 final ProcessRecord proc = procs.valueAt(j);
5340 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5341 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5351 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5352 // If there are no longer any background processes running,
5353 // and the app that died was not running instrumentation,
5354 // then tell everyone we are now low on memory.
5355 boolean haveBg = false;
5356 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5357 ProcessRecord rec = mLruProcesses.get(i);
5358 if (rec.thread != null
5359 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5366 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5368 long now = SystemClock.uptimeMillis();
5369 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5372 mLastMemUsageReportTime = now;
5375 final ArrayList<ProcessMemInfo> memInfos
5376 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5377 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5378 long now = SystemClock.uptimeMillis();
5379 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5380 ProcessRecord rec = mLruProcesses.get(i);
5381 if (rec == dyingProc || rec.thread == null) {
5385 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5386 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5388 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5389 // The low memory report is overriding any current
5390 // state for a GC request. Make sure to do
5391 // heavy/important/visible/foreground processes first.
5392 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5393 rec.lastRequestedGc = 0;
5395 rec.lastRequestedGc = rec.lastLowMemory;
5397 rec.reportLowMemory = true;
5398 rec.lastLowMemory = now;
5399 mProcessesToGc.remove(rec);
5400 addProcessToGcListLocked(rec);
5404 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5405 mHandler.sendMessage(msg);
5407 scheduleAppGcsLocked();
5411 final void appDiedLocked(ProcessRecord app) {
5412 appDiedLocked(app, app.pid, app.thread, false);
5415 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5416 boolean fromBinderDied) {
5417 // First check if this ProcessRecord is actually active for the pid.
5418 synchronized (mPidsSelfLocked) {
5419 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5420 if (curProc != app) {
5421 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5426 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5427 synchronized (stats) {
5428 stats.noteProcessDiedLocked(app.info.uid, pid);
5432 if (!fromBinderDied) {
5433 killProcessQuiet(pid);
5435 killProcessGroup(app.uid, pid);
5439 // Clean up already done if the process has been re-started.
5440 if (app.pid == pid && app.thread != null &&
5441 app.thread.asBinder() == thread.asBinder()) {
5442 boolean doLowMem = app.instr == null;
5443 boolean doOomAdj = doLowMem;
5444 if (!app.killedByAm) {
5445 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5446 + ProcessList.makeOomAdjString(app.setAdj)
5447 + ProcessList.makeProcStateString(app.setProcState));
5448 mAllowLowerMemLevel = true;
5450 // Note that we always want to do oom adj to update our state with the
5451 // new number of procs.
5452 mAllowLowerMemLevel = false;
5455 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5456 app.setAdj, app.setProcState);
5457 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5458 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5459 handleAppDiedLocked(app, false, true);
5462 updateOomAdjLocked();
5465 doLowMemReportIfNeededLocked(app);
5467 } else if (app.pid != pid) {
5468 // A new process has already been started.
5469 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5470 + ") has died and restarted (pid " + app.pid + ").");
5471 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5472 } else if (DEBUG_PROCESSES) {
5473 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5474 + thread.asBinder());
5479 * If a stack trace dump file is configured, dump process stack traces.
5480 * @param clearTraces causes the dump file to be erased prior to the new
5481 * traces being written, if true; when false, the new traces will be
5482 * appended to any existing file content.
5483 * @param firstPids of dalvik VM processes to dump stack traces for first
5484 * @param lastPids of dalvik VM processes to dump stack traces for last
5485 * @param nativePids optional list of native pids to dump stack crawls
5487 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5488 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5489 ArrayList<Integer> nativePids) {
5490 ArrayList<Integer> extraPids = null;
5492 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5493 // of the top users at the time of the request.
5494 if (processCpuTracker != null) {
5495 processCpuTracker.init();
5498 } catch (InterruptedException ignored) {
5501 processCpuTracker.update();
5503 // We'll take the stack crawls of just the top apps using CPU.
5504 final int N = processCpuTracker.countWorkingStats();
5505 extraPids = new ArrayList<>();
5506 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5507 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5508 if (lastPids.indexOfKey(stats.pid) >= 0) {
5509 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5511 extraPids.add(stats.pid);
5512 } else if (DEBUG_ANR) {
5513 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5519 boolean useTombstonedForJavaTraces = false;
5522 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5523 if (tracesDirProp.isEmpty()) {
5524 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5525 // dumping scheme. All traces are written to a global trace file (usually
5526 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5527 // the file if requested.
5529 // This mode of operation will be removed in the near future.
5532 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5533 if (globalTracesPath.isEmpty()) {
5534 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5538 tracesFile = new File(globalTracesPath);
5540 if (clearTraces && tracesFile.exists()) {
5541 tracesFile.delete();
5544 tracesFile.createNewFile();
5545 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5546 } catch (IOException e) {
5547 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5551 File tracesDir = new File(tracesDirProp);
5552 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5553 // Each set of ANR traces is written to a separate file and dumpstate will process
5554 // all such files and add them to a captured bug report if they're recent enough.
5555 maybePruneOldTraces(tracesDir);
5557 // NOTE: We should consider creating the file in native code atomically once we've
5558 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5560 tracesFile = createAnrDumpFile(tracesDir);
5561 if (tracesFile == null) {
5565 useTombstonedForJavaTraces = true;
5568 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5569 useTombstonedForJavaTraces);
5573 @GuardedBy("ActivityManagerService.class")
5574 private static SimpleDateFormat sAnrFileDateFormat;
5576 private static synchronized File createAnrDumpFile(File tracesDir) {
5577 if (sAnrFileDateFormat == null) {
5578 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5581 final String formattedDate = sAnrFileDateFormat.format(new Date());
5582 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5585 if (anrFile.createNewFile()) {
5586 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5589 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5591 } catch (IOException ioe) {
5592 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5599 * Prune all trace files that are more than a day old.
5601 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5602 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5603 * since it's the system_server that creates trace files for most ANRs.
5605 private static void maybePruneOldTraces(File tracesDir) {
5606 final long now = System.currentTimeMillis();
5607 final File[] traceFiles = tracesDir.listFiles();
5609 if (traceFiles != null) {
5610 for (File file : traceFiles) {
5611 if ((now - file.lastModified()) > DAY_IN_MILLIS) {
5612 if (!file.delete()) {
5613 Slog.w(TAG, "Unable to prune stale trace file: " + file);
5621 * Legacy code, do not use. Existing users will be deleted.
5626 public static class DumpStackFileObserver extends FileObserver {
5627 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5628 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5630 private final String mTracesPath;
5631 private boolean mClosed;
5633 public DumpStackFileObserver(String tracesPath) {
5634 super(tracesPath, FileObserver.CLOSE_WRITE);
5635 mTracesPath = tracesPath;
5639 public synchronized void onEvent(int event, String path) {
5644 public long dumpWithTimeout(int pid, long timeout) {
5645 sendSignal(pid, SIGNAL_QUIT);
5646 final long start = SystemClock.elapsedRealtime();
5648 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5649 synchronized (this) {
5651 wait(waitTime); // Wait for traces file to be closed.
5652 } catch (InterruptedException e) {
5657 // This avoids a corner case of passing a negative time to the native
5658 // trace in case we've already hit the overall timeout.
5659 final long timeWaited = SystemClock.elapsedRealtime() - start;
5660 if (timeWaited >= timeout) {
5665 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5666 ". Attempting native stack collection.");
5668 final long nativeDumpTimeoutMs = Math.min(
5669 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5671 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5672 (int) (nativeDumpTimeoutMs / 1000));
5675 final long end = SystemClock.elapsedRealtime();
5678 return (end - start);
5683 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5684 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5685 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5686 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5689 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5690 final long timeStart = SystemClock.elapsedRealtime();
5691 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5692 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5693 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5696 return SystemClock.elapsedRealtime() - timeStart;
5699 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5700 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5701 boolean useTombstonedForJavaTraces) {
5703 // We don't need any sort of inotify based monitoring when we're dumping traces via
5704 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5705 // control of all writes to the file in question.
5706 final DumpStackFileObserver observer;
5707 if (useTombstonedForJavaTraces) {
5710 // Use a FileObserver to detect when traces finish writing.
5711 // The order of traces is considered important to maintain for legibility.
5712 observer = new DumpStackFileObserver(tracesFile);
5715 // We must complete all stack dumps within 20 seconds.
5716 long remainingTime = 20 * 1000;
5718 if (observer != null) {
5719 observer.startWatching();
5722 // First collect all of the stacks of the most important pids.
5723 if (firstPids != null) {
5724 int num = firstPids.size();
5725 for (int i = 0; i < num; i++) {
5726 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5727 + firstPids.get(i));
5728 final long timeTaken;
5729 if (useTombstonedForJavaTraces) {
5730 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5732 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5735 remainingTime -= timeTaken;
5736 if (remainingTime <= 0) {
5737 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5738 "); deadline exceeded.");
5743 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5748 // Next collect the stacks of the native pids
5749 if (nativePids != null) {
5750 for (int pid : nativePids) {
5751 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5752 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5754 final long start = SystemClock.elapsedRealtime();
5755 Debug.dumpNativeBacktraceToFileTimeout(
5756 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5757 final long timeTaken = SystemClock.elapsedRealtime() - start;
5759 remainingTime -= timeTaken;
5760 if (remainingTime <= 0) {
5761 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5762 "); deadline exceeded.");
5767 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5772 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5773 if (extraPids != null) {
5774 for (int pid : extraPids) {
5775 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5777 final long timeTaken;
5778 if (useTombstonedForJavaTraces) {
5779 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5781 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5784 remainingTime -= timeTaken;
5785 if (remainingTime <= 0) {
5786 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5787 "); deadline exceeded.");
5792 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5797 if (observer != null) {
5798 observer.stopWatching();
5803 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5804 if (true || Build.IS_USER) {
5807 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5808 if (tracesPath == null || tracesPath.length() == 0) {
5812 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5813 StrictMode.allowThreadDiskWrites();
5815 final File tracesFile = new File(tracesPath);
5816 final File tracesDir = tracesFile.getParentFile();
5817 final File tracesTmp = new File(tracesDir, "__tmp__");
5819 if (tracesFile.exists()) {
5821 tracesFile.renameTo(tracesTmp);
5823 StringBuilder sb = new StringBuilder();
5824 Time tobj = new Time();
5825 tobj.set(System.currentTimeMillis());
5826 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5828 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5829 sb.append(" since ");
5831 FileOutputStream fos = new FileOutputStream(tracesFile);
5832 fos.write(sb.toString().getBytes());
5834 fos.write("\n*** No application process!".getBytes());
5837 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5838 } catch (IOException e) {
5839 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5844 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5845 firstPids.add(app.pid);
5846 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5849 File lastTracesFile = null;
5850 File curTracesFile = null;
5851 for (int i=9; i>=0; i--) {
5852 String name = String.format(Locale.US, "slow%02d.txt", i);
5853 curTracesFile = new File(tracesDir, name);
5854 if (curTracesFile.exists()) {
5855 if (lastTracesFile != null) {
5856 curTracesFile.renameTo(lastTracesFile);
5858 curTracesFile.delete();
5861 lastTracesFile = curTracesFile;
5863 tracesFile.renameTo(curTracesFile);
5864 if (tracesTmp.exists()) {
5865 tracesTmp.renameTo(tracesFile);
5868 StrictMode.setThreadPolicy(oldPolicy);
5872 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5873 if (!mLaunchWarningShown) {
5874 mLaunchWarningShown = true;
5875 mUiHandler.post(new Runnable() {
5878 synchronized (ActivityManagerService.this) {
5879 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5881 mUiHandler.postDelayed(new Runnable() {
5884 synchronized (ActivityManagerService.this) {
5886 mLaunchWarningShown = false;
5897 public boolean clearApplicationUserData(final String packageName,
5898 final IPackageDataObserver observer, int userId) {
5899 enforceNotIsolatedCaller("clearApplicationUserData");
5900 int uid = Binder.getCallingUid();
5901 int pid = Binder.getCallingPid();
5902 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5903 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5905 final ApplicationInfo appInfo;
5906 final boolean isInstantApp;
5908 long callingId = Binder.clearCallingIdentity();
5910 IPackageManager pm = AppGlobals.getPackageManager();
5911 synchronized(this) {
5912 // Instant packages are not protected
5913 if (getPackageManagerInternalLocked().isPackageDataProtected(
5914 resolvedUserId, packageName)) {
5915 throw new SecurityException(
5916 "Cannot clear data for a protected package: " + packageName);
5919 ApplicationInfo applicationInfo = null;
5921 applicationInfo = pm.getApplicationInfo(packageName,
5922 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5923 } catch (RemoteException e) {
5926 appInfo = applicationInfo;
5928 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5930 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5931 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5932 throw new SecurityException("PID " + pid + " does not have permission "
5933 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5934 + " of package " + packageName);
5937 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5938 .hasInstantApplicationMetadata(packageName, resolvedUserId);
5939 final boolean isUninstalledAppWithoutInstantMetadata =
5940 (appInfo == null && !hasInstantMetadata);
5941 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5942 || hasInstantMetadata;
5943 final boolean canAccessInstantApps = checkComponentPermission(
5944 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5945 == PackageManager.PERMISSION_GRANTED;
5947 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5948 && !canAccessInstantApps)) {
5949 Slog.w(TAG, "Invalid packageName: " + packageName);
5950 if (observer != null) {
5952 observer.onRemoveCompleted(packageName, false);
5953 } catch (RemoteException e) {
5954 Slog.i(TAG, "Observer no longer exists.");
5960 if (appInfo != null) {
5961 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5962 // Remove all tasks match the cleared application package and user
5963 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5964 final TaskRecord tr = mRecentTasks.get(i);
5965 final String taskPackageName =
5966 tr.getBaseIntent().getComponent().getPackageName();
5967 if (tr.userId != resolvedUserId) continue;
5968 if (!taskPackageName.equals(packageName)) continue;
5969 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5970 REMOVE_FROM_RECENTS);
5975 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5977 public void onRemoveCompleted(String packageName, boolean succeeded)
5978 throws RemoteException {
5979 if (appInfo != null) {
5980 synchronized (ActivityManagerService.this) {
5981 finishForceStopPackageLocked(packageName, appInfo.uid);
5984 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5985 Uri.fromParts("package", packageName, null));
5986 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5987 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5988 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5990 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5991 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5992 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5995 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5996 null, null, null, null, false, false, resolvedUserId);
5999 if (observer != null) {
6000 observer.onRemoveCompleted(packageName, succeeded);
6006 // Clear application user data
6007 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6009 if (appInfo != null) {
6010 synchronized (this) {
6011 // Remove all permissions granted from/to this package
6012 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6015 // Reset notification settings.
6016 INotificationManager inm = NotificationManager.getService();
6017 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6019 } catch (RemoteException e) {
6022 Binder.restoreCallingIdentity(callingId);
6028 public void killBackgroundProcesses(final String packageName, int userId) {
6029 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6030 != PackageManager.PERMISSION_GRANTED &&
6031 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6032 != PackageManager.PERMISSION_GRANTED) {
6033 String msg = "Permission Denial: killBackgroundProcesses() from pid="
6034 + Binder.getCallingPid()
6035 + ", uid=" + Binder.getCallingUid()
6036 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6038 throw new SecurityException(msg);
6041 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6042 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6043 long callingId = Binder.clearCallingIdentity();
6045 IPackageManager pm = AppGlobals.getPackageManager();
6046 synchronized(this) {
6049 appId = UserHandle.getAppId(
6050 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6051 } catch (RemoteException e) {
6054 Slog.w(TAG, "Invalid packageName: " + packageName);
6057 killPackageProcessesLocked(packageName, appId, userId,
6058 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6061 Binder.restoreCallingIdentity(callingId);
6066 public void killAllBackgroundProcesses() {
6067 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6068 != PackageManager.PERMISSION_GRANTED) {
6069 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6070 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6071 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6073 throw new SecurityException(msg);
6076 final long callingId = Binder.clearCallingIdentity();
6078 synchronized (this) {
6079 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6080 final int NP = mProcessNames.getMap().size();
6081 for (int ip = 0; ip < NP; ip++) {
6082 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6083 final int NA = apps.size();
6084 for (int ia = 0; ia < NA; ia++) {
6085 final ProcessRecord app = apps.valueAt(ia);
6086 if (app.persistent) {
6087 // We don't kill persistent processes.
6092 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6099 final int N = procs.size();
6100 for (int i = 0; i < N; i++) {
6101 removeProcessLocked(procs.get(i), false, true, "kill all background");
6104 mAllowLowerMemLevel = true;
6106 updateOomAdjLocked();
6107 doLowMemReportIfNeededLocked(null);
6110 Binder.restoreCallingIdentity(callingId);
6115 * Kills all background processes, except those matching any of the
6116 * specified properties.
6118 * @param minTargetSdk the target SDK version at or above which to preserve
6119 * processes, or {@code -1} to ignore the target SDK
6120 * @param maxProcState the process state at or below which to preserve
6121 * processes, or {@code -1} to ignore the process state
6123 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6124 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6125 != PackageManager.PERMISSION_GRANTED) {
6126 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6127 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6128 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6130 throw new SecurityException(msg);
6133 final long callingId = Binder.clearCallingIdentity();
6135 synchronized (this) {
6136 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6137 final int NP = mProcessNames.getMap().size();
6138 for (int ip = 0; ip < NP; ip++) {
6139 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6140 final int NA = apps.size();
6141 for (int ia = 0; ia < NA; ia++) {
6142 final ProcessRecord app = apps.valueAt(ia);
6145 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6146 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6153 final int N = procs.size();
6154 for (int i = 0; i < N; i++) {
6155 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6159 Binder.restoreCallingIdentity(callingId);
6164 public void forceStopPackage(final String packageName, int userId) {
6165 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6166 != PackageManager.PERMISSION_GRANTED) {
6167 String msg = "Permission Denial: forceStopPackage() from pid="
6168 + Binder.getCallingPid()
6169 + ", uid=" + Binder.getCallingUid()
6170 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6172 throw new SecurityException(msg);
6174 final int callingPid = Binder.getCallingPid();
6175 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6176 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6177 long callingId = Binder.clearCallingIdentity();
6179 IPackageManager pm = AppGlobals.getPackageManager();
6180 synchronized(this) {
6181 int[] users = userId == UserHandle.USER_ALL
6182 ? mUserController.getUsers() : new int[] { userId };
6183 for (int user : users) {
6186 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6188 } catch (RemoteException e) {
6191 Slog.w(TAG, "Invalid packageName: " + packageName);
6195 pm.setPackageStoppedState(packageName, true, user);
6196 } catch (RemoteException e) {
6197 } catch (IllegalArgumentException e) {
6198 Slog.w(TAG, "Failed trying to unstop package "
6199 + packageName + ": " + e);
6201 if (mUserController.isUserRunningLocked(user, 0)) {
6202 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6203 finishForceStopPackageLocked(packageName, pkgUid);
6208 Binder.restoreCallingIdentity(callingId);
6213 public void addPackageDependency(String packageName) {
6214 synchronized (this) {
6215 int callingPid = Binder.getCallingPid();
6216 if (callingPid == myPid()) {
6221 synchronized (mPidsSelfLocked) {
6222 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6225 if (proc.pkgDeps == null) {
6226 proc.pkgDeps = new ArraySet<String>(1);
6228 proc.pkgDeps.add(packageName);
6234 * The pkg name and app id have to be specified.
6237 public void killApplication(String pkg, int appId, int userId, String reason) {
6241 // Make sure the uid is valid.
6243 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6246 int callerUid = Binder.getCallingUid();
6247 // Only the system server can kill an application
6248 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6249 // Post an aysnc message to kill the application
6250 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6253 Bundle bundle = new Bundle();
6254 bundle.putString("pkg", pkg);
6255 bundle.putString("reason", reason);
6257 mHandler.sendMessage(msg);
6259 throw new SecurityException(callerUid + " cannot kill pkg: " +
6265 public void closeSystemDialogs(String reason) {
6266 enforceNotIsolatedCaller("closeSystemDialogs");
6268 final int pid = Binder.getCallingPid();
6269 final int uid = Binder.getCallingUid();
6270 final long origId = Binder.clearCallingIdentity();
6272 synchronized (this) {
6273 // Only allow this from foreground processes, so that background
6274 // applications can't abuse it to prevent system UI from being shown.
6275 if (uid >= FIRST_APPLICATION_UID) {
6277 synchronized (mPidsSelfLocked) {
6278 proc = mPidsSelfLocked.get(pid);
6280 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6281 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6282 + " from background process " + proc);
6286 closeSystemDialogsLocked(reason);
6289 Binder.restoreCallingIdentity(origId);
6293 void closeSystemDialogsLocked(String reason) {
6294 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6295 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6296 | Intent.FLAG_RECEIVER_FOREGROUND);
6297 if (reason != null) {
6298 intent.putExtra("reason", reason);
6300 mWindowManager.closeSystemDialogs(reason);
6302 mStackSupervisor.closeSystemDialogsLocked();
6304 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6305 AppOpsManager.OP_NONE, null, false, false,
6306 -1, SYSTEM_UID, UserHandle.USER_ALL);
6310 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6311 enforceNotIsolatedCaller("getProcessMemoryInfo");
6312 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6313 for (int i=pids.length-1; i>=0; i--) {
6316 synchronized (this) {
6317 synchronized (mPidsSelfLocked) {
6318 proc = mPidsSelfLocked.get(pids[i]);
6319 oomAdj = proc != null ? proc.setAdj : 0;
6322 infos[i] = new Debug.MemoryInfo();
6323 Debug.getMemoryInfo(pids[i], infos[i]);
6325 synchronized (this) {
6326 if (proc.thread != null && proc.setAdj == oomAdj) {
6327 // Record this for posterity if the process has been stable.
6328 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6329 infos[i].getTotalUss(), false, proc.pkgList);
6338 public long[] getProcessPss(int[] pids) {
6339 enforceNotIsolatedCaller("getProcessPss");
6340 long[] pss = new long[pids.length];
6341 for (int i=pids.length-1; i>=0; i--) {
6344 synchronized (this) {
6345 synchronized (mPidsSelfLocked) {
6346 proc = mPidsSelfLocked.get(pids[i]);
6347 oomAdj = proc != null ? proc.setAdj : 0;
6350 long[] tmpUss = new long[1];
6351 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6353 synchronized (this) {
6354 if (proc.thread != null && proc.setAdj == oomAdj) {
6355 // Record this for posterity if the process has been stable.
6356 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6365 public void killApplicationProcess(String processName, int uid) {
6366 if (processName == null) {
6370 int callerUid = Binder.getCallingUid();
6371 // Only the system server can kill an application
6372 if (callerUid == SYSTEM_UID) {
6373 synchronized (this) {
6374 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6375 if (app != null && app.thread != null) {
6377 app.thread.scheduleSuicide();
6378 } catch (RemoteException e) {
6379 // If the other end already died, then our work here is done.
6382 Slog.w(TAG, "Process/uid not found attempting kill of "
6383 + processName + " / " + uid);
6387 throw new SecurityException(callerUid + " cannot kill app process: " +
6392 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6393 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6394 false, true, false, false, UserHandle.getUserId(uid), reason);
6397 private void finishForceStopPackageLocked(final String packageName, int uid) {
6398 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6399 Uri.fromParts("package", packageName, null));
6400 if (!mProcessesReady) {
6401 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6402 | Intent.FLAG_RECEIVER_FOREGROUND);
6404 intent.putExtra(Intent.EXTRA_UID, uid);
6405 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6406 broadcastIntentLocked(null, null, intent,
6407 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6408 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6412 private final boolean killPackageProcessesLocked(String packageName, int appId,
6413 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6414 boolean doit, boolean evenPersistent, String reason) {
6415 ArrayList<ProcessRecord> procs = new ArrayList<>();
6417 // Remove all processes this package may have touched: all with the
6418 // same UID (except for the system or root user), and all whose name
6419 // matches the package name.
6420 final int NP = mProcessNames.getMap().size();
6421 for (int ip=0; ip<NP; ip++) {
6422 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6423 final int NA = apps.size();
6424 for (int ia=0; ia<NA; ia++) {
6425 ProcessRecord app = apps.valueAt(ia);
6426 if (app.persistent && !evenPersistent) {
6427 // we don't kill persistent processes
6437 // Skip process if it doesn't meet our oom adj requirement.
6438 if (app.setAdj < minOomAdj) {
6442 // If no package is specified, we call all processes under the
6444 if (packageName == null) {
6445 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6448 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6451 // Package has been specified, we want to hit all processes
6452 // that match it. We need to qualify this by the processes
6453 // that are running under the specified app and user ID.
6455 final boolean isDep = app.pkgDeps != null
6456 && app.pkgDeps.contains(packageName);
6457 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6460 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6463 if (!app.pkgList.containsKey(packageName) && !isDep) {
6468 // Process has passed all conditions, kill it!
6477 int N = procs.size();
6478 for (int i=0; i<N; i++) {
6479 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6481 updateOomAdjLocked();
6485 private void cleanupDisabledPackageComponentsLocked(
6486 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6488 Set<String> disabledClasses = null;
6489 boolean packageDisabled = false;
6490 IPackageManager pm = AppGlobals.getPackageManager();
6492 if (changedClasses == null) {
6493 // Nothing changed...
6497 // Determine enable/disable state of the package and its components.
6498 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6499 for (int i = changedClasses.length - 1; i >= 0; i--) {
6500 final String changedClass = changedClasses[i];
6502 if (changedClass.equals(packageName)) {
6504 // Entire package setting changed
6505 enabled = pm.getApplicationEnabledSetting(packageName,
6506 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6507 } catch (Exception e) {
6508 // No such package/component; probably racing with uninstall. In any
6509 // event it means we have nothing further to do here.
6512 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6513 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6514 if (packageDisabled) {
6515 // Entire package is disabled.
6516 // No need to continue to check component states.
6517 disabledClasses = null;
6522 enabled = pm.getComponentEnabledSetting(
6523 new ComponentName(packageName, changedClass),
6524 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6525 } catch (Exception e) {
6526 // As above, probably racing with uninstall.
6529 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6530 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6531 if (disabledClasses == null) {
6532 disabledClasses = new ArraySet<>(changedClasses.length);
6534 disabledClasses.add(changedClass);
6539 if (!packageDisabled && disabledClasses == null) {
6540 // Nothing to do here...
6544 // Clean-up disabled activities.
6545 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6546 packageName, disabledClasses, true, false, userId) && mBooted) {
6547 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6548 mStackSupervisor.scheduleIdleLocked();
6551 // Clean-up disabled tasks
6552 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6554 // Clean-up disabled services.
6555 mServices.bringDownDisabledPackageServicesLocked(
6556 packageName, disabledClasses, userId, false, killProcess, true);
6558 // Clean-up disabled providers.
6559 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6560 mProviderMap.collectPackageProvidersLocked(
6561 packageName, disabledClasses, true, false, userId, providers);
6562 for (int i = providers.size() - 1; i >= 0; i--) {
6563 removeDyingProviderLocked(null, providers.get(i), true);
6566 // Clean-up disabled broadcast receivers.
6567 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6568 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6569 packageName, disabledClasses, userId, true);
6574 final boolean clearBroadcastQueueForUserLocked(int userId) {
6575 boolean didSomething = false;
6576 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6577 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6578 null, null, userId, true);
6580 return didSomething;
6583 final boolean forceStopPackageLocked(String packageName, int appId,
6584 boolean callerWillRestart, boolean purgeCache, boolean doit,
6585 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6588 if (userId == UserHandle.USER_ALL && packageName == null) {
6589 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6592 if (appId < 0 && packageName != null) {
6594 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6595 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6596 } catch (RemoteException e) {
6601 if (packageName != null) {
6602 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6603 + " user=" + userId + ": " + reason);
6605 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6608 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6611 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6612 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6613 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6615 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6617 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6618 packageName, null, doit, evenPersistent, userId)) {
6622 didSomething = true;
6625 if (mServices.bringDownDisabledPackageServicesLocked(
6626 packageName, null, userId, evenPersistent, true, doit)) {
6630 didSomething = true;
6633 if (packageName == null) {
6634 // Remove all sticky broadcasts from this user.
6635 mStickyBroadcasts.remove(userId);
6638 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6639 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6640 userId, providers)) {
6644 didSomething = true;
6646 for (i = providers.size() - 1; i >= 0; i--) {
6647 removeDyingProviderLocked(null, providers.get(i), true);
6650 // Remove transient permissions granted from/to this package/user
6651 removeUriPermissionsForPackageLocked(packageName, userId, false);
6654 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6655 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6656 packageName, null, userId, doit);
6660 if (packageName == null || uninstalling) {
6661 // Remove pending intents. For now we only do this when force
6662 // stopping users, because we have some problems when doing this
6663 // for packages -- app widgets are not currently cleaned up for
6664 // such packages, so they can be left with bad pending intents.
6665 if (mIntentSenderRecords.size() > 0) {
6666 Iterator<WeakReference<PendingIntentRecord>> it
6667 = mIntentSenderRecords.values().iterator();
6668 while (it.hasNext()) {
6669 WeakReference<PendingIntentRecord> wpir = it.next();
6674 PendingIntentRecord pir = wpir.get();
6679 if (packageName == null) {
6680 // Stopping user, remove all objects for the user.
6681 if (pir.key.userId != userId) {
6682 // Not the same user, skip it.
6686 if (UserHandle.getAppId(pir.uid) != appId) {
6687 // Different app id, skip it.
6690 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6691 // Different user, skip it.
6694 if (!pir.key.packageName.equals(packageName)) {
6695 // Different package, skip it.
6702 didSomething = true;
6704 makeIntentSenderCanceledLocked(pir);
6705 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6706 pir.key.activity.pendingResults.remove(pir.ref);
6713 if (purgeCache && packageName != null) {
6714 AttributeCache ac = AttributeCache.instance();
6716 ac.removePackage(packageName);
6720 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6721 mStackSupervisor.scheduleIdleLocked();
6725 return didSomething;
6728 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6729 return removeProcessNameLocked(name, uid, null);
6732 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6733 final ProcessRecord expecting) {
6734 ProcessRecord old = mProcessNames.get(name, uid);
6735 // Only actually remove when the currently recorded value matches the
6736 // record that we expected; if it doesn't match then we raced with a
6737 // newly created process and we don't want to destroy the new one.
6738 if ((expecting == null) || (old == expecting)) {
6739 mProcessNames.remove(name, uid);
6741 if (old != null && old.uidRecord != null) {
6742 old.uidRecord.numProcs--;
6743 if (old.uidRecord.numProcs == 0) {
6744 // No more processes using this uid, tell clients it is gone.
6745 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6746 "No more processes in " + old.uidRecord);
6747 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6748 EventLogTags.writeAmUidStopped(uid);
6749 mActiveUids.remove(uid);
6750 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6752 old.uidRecord = null;
6754 mIsolatedProcesses.remove(uid);
6758 private final void addProcessNameLocked(ProcessRecord proc) {
6759 // We shouldn't already have a process under this name, but just in case we
6760 // need to clean up whatever may be there now.
6761 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6762 if (old == proc && proc.persistent) {
6763 // We are re-adding a persistent process. Whatevs! Just leave it there.
6764 Slog.w(TAG, "Re-adding persistent process " + proc);
6765 } else if (old != null) {
6766 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6768 UidRecord uidRec = mActiveUids.get(proc.uid);
6769 if (uidRec == null) {
6770 uidRec = new UidRecord(proc.uid);
6771 // This is the first appearance of the uid, report it now!
6772 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6773 "Creating new process uid: " + uidRec);
6774 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6775 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6776 uidRec.setWhitelist = uidRec.curWhitelist = true;
6778 uidRec.updateHasInternetPermission();
6779 mActiveUids.put(proc.uid, uidRec);
6780 EventLogTags.writeAmUidRunning(uidRec.uid);
6781 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6783 proc.uidRecord = uidRec;
6785 // Reset render thread tid if it was already set, so new process can set it again.
6786 proc.renderThreadTid = 0;
6788 mProcessNames.put(proc.processName, proc.uid, proc);
6789 if (proc.isolated) {
6790 mIsolatedProcesses.put(proc.uid, proc);
6794 boolean removeProcessLocked(ProcessRecord app,
6795 boolean callerWillRestart, boolean allowRestart, String reason) {
6796 final String name = app.processName;
6797 final int uid = app.uid;
6798 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6799 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6801 ProcessRecord old = mProcessNames.get(name, uid);
6803 // This process is no longer active, so nothing to do.
6804 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6807 removeProcessNameLocked(name, uid);
6808 if (mHeavyWeightProcess == app) {
6809 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6810 mHeavyWeightProcess.userId, 0));
6811 mHeavyWeightProcess = null;
6813 boolean needRestart = false;
6814 if (app.pid > 0 && app.pid != MY_PID) {
6816 synchronized (mPidsSelfLocked) {
6817 mPidsSelfLocked.remove(pid);
6818 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6820 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6821 boolean willRestart = false;
6822 if (app.persistent && !app.isolated) {
6823 if (!callerWillRestart) {
6829 app.kill(reason, true);
6831 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6832 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6834 handleAppDiedLocked(app, willRestart, allowRestart);
6836 removeLruProcessLocked(app);
6837 addAppLocked(app.info, null, false, null /* ABI override */);
6840 mRemovedProcesses.add(app);
6846 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6847 cleanupAppInLaunchingProvidersLocked(app, true);
6848 removeProcessLocked(app, false, true, "timeout publishing content providers");
6851 private final void processStartTimedOutLocked(ProcessRecord app) {
6852 final int pid = app.pid;
6853 boolean gone = false;
6854 synchronized (mPidsSelfLocked) {
6855 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6856 if (knownApp != null && knownApp.thread == null) {
6857 mPidsSelfLocked.remove(pid);
6863 Slog.w(TAG, "Process " + app + " failed to attach");
6864 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6865 pid, app.uid, app.processName);
6866 removeProcessNameLocked(app.processName, app.uid);
6867 if (mHeavyWeightProcess == app) {
6868 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6869 mHeavyWeightProcess.userId, 0));
6870 mHeavyWeightProcess = null;
6872 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6873 // Take care of any launching providers waiting for this process.
6874 cleanupAppInLaunchingProvidersLocked(app, true);
6875 // Take care of any services that are waiting for the process.
6876 mServices.processStartTimedOutLocked(app);
6877 app.kill("start timeout", true);
6879 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6881 removeLruProcessLocked(app);
6882 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6883 Slog.w(TAG, "Unattached app died before backup, skipping");
6884 mHandler.post(new Runnable() {
6888 IBackupManager bm = IBackupManager.Stub.asInterface(
6889 ServiceManager.getService(Context.BACKUP_SERVICE));
6890 bm.agentDisconnected(app.info.packageName);
6891 } catch (RemoteException e) {
6892 // Can't happen; the backup manager is local
6897 if (isPendingBroadcastProcessLocked(pid)) {
6898 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6899 skipPendingBroadcastLocked(pid);
6902 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6906 private final boolean attachApplicationLocked(IApplicationThread thread,
6909 // Find the application record that is being attached... either via
6910 // the pid if we are running in multiple processes, or just pull the
6911 // next app record if we are emulating process with anonymous threads.
6913 long startTime = SystemClock.uptimeMillis();
6914 if (pid != MY_PID && pid >= 0) {
6915 synchronized (mPidsSelfLocked) {
6916 app = mPidsSelfLocked.get(pid);
6923 Slog.w(TAG, "No pending application record for pid " + pid
6924 + " (IApplicationThread " + thread + "); dropping process");
6925 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6926 if (pid > 0 && pid != MY_PID) {
6927 killProcessQuiet(pid);
6928 //TODO: killProcessGroup(app.info.uid, pid);
6931 thread.scheduleExit();
6932 } catch (Exception e) {
6933 // Ignore exceptions.
6939 // If this application record is still attached to a previous
6940 // process, clean it up now.
6941 if (app.thread != null) {
6942 handleAppDiedLocked(app, true, true);
6945 // Tell the process all about itself.
6947 if (DEBUG_ALL) Slog.v(
6948 TAG, "Binding process pid " + pid + " to record " + app);
6950 final String processName = app.processName;
6952 AppDeathRecipient adr = new AppDeathRecipient(
6954 thread.asBinder().linkToDeath(adr, 0);
6955 app.deathRecipient = adr;
6956 } catch (RemoteException e) {
6957 app.resetPackageList(mProcessStats);
6958 startProcessLocked(app, "link fail", processName);
6962 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6964 app.makeActive(thread, mProcessStats);
6965 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6966 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6967 app.forcingToImportant = null;
6968 updateProcessForegroundLocked(app, false, false);
6969 app.hasShownUi = false;
6970 app.debugging = false;
6972 app.killedByAm = false;
6976 // We carefully use the same state that PackageManager uses for
6977 // filtering, since we use this flag to decide if we need to install
6978 // providers when user is unlocked later
6979 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6981 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6983 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6984 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6986 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6987 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6989 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6992 checkTime(startTime, "attachApplicationLocked: before bindApplication");
6995 Slog.i(TAG, "Launching preboot mode app: " + app);
6998 if (DEBUG_ALL) Slog.v(
6999 TAG, "New app record " + app
7000 + " thread=" + thread.asBinder() + " pid=" + pid);
7002 int testMode = ApplicationThreadConstants.DEBUG_OFF;
7003 if (mDebugApp != null && mDebugApp.equals(processName)) {
7004 testMode = mWaitForDebugger
7005 ? ApplicationThreadConstants.DEBUG_WAIT
7006 : ApplicationThreadConstants.DEBUG_ON;
7007 app.debugging = true;
7008 if (mDebugTransient) {
7009 mDebugApp = mOrigDebugApp;
7010 mWaitForDebugger = mOrigWaitForDebugger;
7014 ProfilerInfo profilerInfo = null;
7015 String agent = null;
7016 if (mProfileApp != null && mProfileApp.equals(processName)) {
7018 profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7019 new ProfilerInfo(mProfilerInfo) : null;
7020 agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7021 } else if (app.instr != null && app.instr.mProfileFile != null) {
7022 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7026 boolean enableTrackAllocation = false;
7027 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7028 enableTrackAllocation = true;
7029 mTrackAllocationApp = null;
7032 // If the app is being launched for restore or full backup, set it up specially
7033 boolean isRestrictedBackupMode = false;
7034 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7035 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7036 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7037 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7038 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7041 if (app.instr != null) {
7042 notifyPackageUse(app.instr.mClass.getPackageName(),
7043 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7045 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7046 + processName + " with config " + getGlobalConfiguration());
7047 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7048 app.compat = compatibilityInfoForPackageLocked(appInfo);
7050 if (profilerInfo != null && profilerInfo.profileFd != null) {
7051 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7054 // We deprecated Build.SERIAL and it is not accessible to
7055 // apps that target the v2 security sandbox. Since access to
7056 // the serial is now behind a permission we push down the value.
7057 String buildSerial = appInfo.targetSandboxVersion < 2
7058 ? sTheRealBuildSerial : Build.UNKNOWN;
7060 // Check if this is a secondary process that should be incorporated into some
7061 // currently active instrumentation. (Note we do this AFTER all of the profiling
7062 // stuff above because profiling can currently happen only in the primary
7063 // instrumentation process.)
7064 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7065 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7066 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7067 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7068 if (aInstr.mTargetProcesses.length == 0) {
7069 // This is the wildcard mode, where every process brought up for
7070 // the target instrumentation should be included.
7071 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7073 aInstr.mRunningProcesses.add(app);
7076 for (String proc : aInstr.mTargetProcesses) {
7077 if (proc.equals(app.processName)) {
7079 aInstr.mRunningProcesses.add(app);
7088 // If we were asked to attach an agent on startup, do so now, before we're binding
7089 // application code.
7090 if (agent != null) {
7091 thread.attachAgent(agent);
7094 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7095 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7096 if (app.instr != null) {
7097 thread.bindApplication(processName, appInfo, providers,
7099 profilerInfo, app.instr.mArguments,
7101 app.instr.mUiAutomationConnection, testMode,
7102 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7103 isRestrictedBackupMode || !normalMode, app.persistent,
7104 new Configuration(getGlobalConfiguration()), app.compat,
7105 getCommonServicesLocked(app.isolated),
7106 mCoreSettingsObserver.getCoreSettingsLocked(),
7109 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7110 null, null, null, testMode,
7111 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7112 isRestrictedBackupMode || !normalMode, app.persistent,
7113 new Configuration(getGlobalConfiguration()), app.compat,
7114 getCommonServicesLocked(app.isolated),
7115 mCoreSettingsObserver.getCoreSettingsLocked(),
7119 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7120 updateLruProcessLocked(app, false, null);
7121 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7122 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7123 } catch (Exception e) {
7124 // todo: Yikes! What should we do? For now we will try to
7125 // start another process, but that could easily get us in
7126 // an infinite loop of restarting processes...
7127 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7129 app.resetPackageList(mProcessStats);
7130 app.unlinkDeathRecipient();
7131 startProcessLocked(app, "bind fail", processName);
7135 // Remove this record from the list of starting applications.
7136 mPersistentStartingProcesses.remove(app);
7137 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7138 "Attach application locked removing on hold: " + app);
7139 mProcessesOnHold.remove(app);
7141 boolean badApp = false;
7142 boolean didSomething = false;
7144 // See if the top visible activity is waiting to run in this process...
7147 if (mStackSupervisor.attachApplicationLocked(app)) {
7148 didSomething = true;
7150 } catch (Exception e) {
7151 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7156 // Find any services that should be running in this process...
7159 didSomething |= mServices.attachApplicationLocked(app, processName);
7160 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7161 } catch (Exception e) {
7162 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7167 // Check if a next-broadcast receiver is in this process...
7168 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7170 didSomething |= sendPendingBroadcastsLocked(app);
7171 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7172 } catch (Exception e) {
7173 // If the app died trying to launch the receiver we declare it 'bad'
7174 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7179 // Check whether the next backup agent is in this process...
7180 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7181 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7182 "New app is backup target, launching agent for " + app);
7183 notifyPackageUse(mBackupTarget.appInfo.packageName,
7184 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7186 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7187 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7188 mBackupTarget.backupMode);
7189 } catch (Exception e) {
7190 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7196 app.kill("error during init", true);
7197 handleAppDiedLocked(app, false, true);
7201 if (!didSomething) {
7202 updateOomAdjLocked();
7203 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7210 public final void attachApplication(IApplicationThread thread) {
7211 synchronized (this) {
7212 int callingPid = Binder.getCallingPid();
7213 final long origId = Binder.clearCallingIdentity();
7214 attachApplicationLocked(thread, callingPid);
7215 Binder.restoreCallingIdentity(origId);
7220 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7221 final long origId = Binder.clearCallingIdentity();
7222 synchronized (this) {
7223 ActivityStack stack = ActivityRecord.getStackLocked(token);
7224 if (stack != null) {
7226 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7227 false /* processPausingActivities */, config);
7228 if (stopProfiling) {
7229 if ((mProfileProc == r.app) && mProfilerInfo != null) {
7230 clearProfilerLocked();
7235 Binder.restoreCallingIdentity(origId);
7238 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7239 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7240 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7243 void enableScreenAfterBoot() {
7244 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7245 SystemClock.uptimeMillis());
7246 mWindowManager.enableScreenAfterBoot();
7248 synchronized (this) {
7249 updateEventDispatchingLocked();
7254 public void showBootMessage(final CharSequence msg, final boolean always) {
7255 if (Binder.getCallingUid() != myUid()) {
7256 throw new SecurityException();
7258 mWindowManager.showBootMessage(msg, always);
7262 public void keyguardGoingAway(int flags) {
7263 enforceNotIsolatedCaller("keyguardGoingAway");
7264 final long token = Binder.clearCallingIdentity();
7266 synchronized (this) {
7267 mKeyguardController.keyguardGoingAway(flags);
7270 Binder.restoreCallingIdentity(token);
7275 * @return whther the keyguard is currently locked.
7277 boolean isKeyguardLocked() {
7278 return mKeyguardController.isKeyguardLocked();
7281 final void finishBooting() {
7282 synchronized (this) {
7283 if (!mBootAnimationComplete) {
7284 mCallFinishBooting = true;
7287 mCallFinishBooting = false;
7290 ArraySet<String> completedIsas = new ArraySet<String>();
7291 for (String abi : Build.SUPPORTED_ABIS) {
7292 zygoteProcess.establishZygoteConnectionForAbi(abi);
7293 final String instructionSet = VMRuntime.getInstructionSet(abi);
7294 if (!completedIsas.contains(instructionSet)) {
7296 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7297 } catch (InstallerException e) {
7298 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7299 e.getMessage() +")");
7301 completedIsas.add(instructionSet);
7305 IntentFilter pkgFilter = new IntentFilter();
7306 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7307 pkgFilter.addDataScheme("package");
7308 mContext.registerReceiver(new BroadcastReceiver() {
7310 public void onReceive(Context context, Intent intent) {
7311 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7313 for (String pkg : pkgs) {
7314 synchronized (ActivityManagerService.this) {
7315 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7316 0, "query restart")) {
7317 setResultCode(Activity.RESULT_OK);
7326 IntentFilter dumpheapFilter = new IntentFilter();
7327 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7328 mContext.registerReceiver(new BroadcastReceiver() {
7330 public void onReceive(Context context, Intent intent) {
7331 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7332 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7334 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7339 // Let system services know.
7340 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7342 synchronized (this) {
7343 // Ensure that any processes we had put on hold are now started
7345 final int NP = mProcessesOnHold.size();
7347 ArrayList<ProcessRecord> procs =
7348 new ArrayList<ProcessRecord>(mProcessesOnHold);
7349 for (int ip=0; ip<NP; ip++) {
7350 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7352 startProcessLocked(procs.get(ip), "on-hold", null);
7356 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7357 // Start looking for apps that are abusing wake locks.
7358 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7359 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7360 // Tell anyone interested that we are done booting!
7361 SystemProperties.set("sys.boot_completed", "1");
7363 // And trigger dev.bootcomplete if we are not showing encryption progress
7364 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7365 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7366 SystemProperties.set("dev.bootcomplete", "1");
7368 mUserController.sendBootCompletedLocked(
7369 new IIntentReceiver.Stub() {
7371 public void performReceive(Intent intent, int resultCode,
7372 String data, Bundle extras, boolean ordered,
7373 boolean sticky, int sendingUser) {
7374 synchronized (ActivityManagerService.this) {
7375 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7380 scheduleStartProfilesLocked();
7386 public void bootAnimationComplete() {
7387 final boolean callFinishBooting;
7388 synchronized (this) {
7389 callFinishBooting = mCallFinishBooting;
7390 mBootAnimationComplete = true;
7392 if (callFinishBooting) {
7393 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7395 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7399 final void ensureBootCompleted() {
7401 boolean enableScreen;
7402 synchronized (this) {
7405 enableScreen = !mBooted;
7410 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7412 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7416 enableScreenAfterBoot();
7421 public final void activityResumed(IBinder token) {
7422 final long origId = Binder.clearCallingIdentity();
7423 synchronized(this) {
7424 ActivityRecord.activityResumedLocked(token);
7425 mWindowManager.notifyAppResumedFinished(token);
7427 Binder.restoreCallingIdentity(origId);
7431 public final void activityPaused(IBinder token) {
7432 final long origId = Binder.clearCallingIdentity();
7433 synchronized(this) {
7434 ActivityStack stack = ActivityRecord.getStackLocked(token);
7435 if (stack != null) {
7436 stack.activityPausedLocked(token, false);
7439 Binder.restoreCallingIdentity(origId);
7443 public final void activityStopped(IBinder token, Bundle icicle,
7444 PersistableBundle persistentState, CharSequence description) {
7445 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7447 // Refuse possible leaked file descriptors
7448 if (icicle != null && icicle.hasFileDescriptors()) {
7449 throw new IllegalArgumentException("File descriptors passed in Bundle");
7452 final long origId = Binder.clearCallingIdentity();
7454 synchronized (this) {
7455 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7457 r.activityStoppedLocked(icicle, persistentState, description);
7463 Binder.restoreCallingIdentity(origId);
7467 public final void activityDestroyed(IBinder token) {
7468 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7469 synchronized (this) {
7470 ActivityStack stack = ActivityRecord.getStackLocked(token);
7471 if (stack != null) {
7472 stack.activityDestroyedLocked(token, "activityDestroyed");
7478 public final void activityRelaunched(IBinder token) {
7479 final long origId = Binder.clearCallingIdentity();
7480 synchronized (this) {
7481 mStackSupervisor.activityRelaunchedLocked(token);
7483 Binder.restoreCallingIdentity(origId);
7487 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7488 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7489 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7490 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7491 synchronized (this) {
7492 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7493 if (record == null) {
7494 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7495 + "found for: " + token);
7497 record.setSizeConfigurations(horizontalSizeConfiguration,
7498 verticalSizeConfigurations, smallestSizeConfigurations);
7503 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7504 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7508 public final void notifyEnterAnimationComplete(IBinder token) {
7509 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7513 public String getCallingPackage(IBinder token) {
7514 synchronized (this) {
7515 ActivityRecord r = getCallingRecordLocked(token);
7516 return r != null ? r.info.packageName : null;
7521 public ComponentName getCallingActivity(IBinder token) {
7522 synchronized (this) {
7523 ActivityRecord r = getCallingRecordLocked(token);
7524 return r != null ? r.intent.getComponent() : null;
7528 private ActivityRecord getCallingRecordLocked(IBinder token) {
7529 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7537 public ComponentName getActivityClassForToken(IBinder token) {
7538 synchronized(this) {
7539 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7543 return r.intent.getComponent();
7548 public String getPackageForToken(IBinder token) {
7549 synchronized(this) {
7550 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7554 return r.packageName;
7559 public boolean isRootVoiceInteraction(IBinder token) {
7560 synchronized(this) {
7561 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7565 return r.rootVoiceInteraction;
7570 public IIntentSender getIntentSender(int type,
7571 String packageName, IBinder token, String resultWho,
7572 int requestCode, Intent[] intents, String[] resolvedTypes,
7573 int flags, Bundle bOptions, int userId) {
7574 enforceNotIsolatedCaller("getIntentSender");
7575 // Refuse possible leaked file descriptors
7576 if (intents != null) {
7577 if (intents.length < 1) {
7578 throw new IllegalArgumentException("Intents array length must be >= 1");
7580 for (int i=0; i<intents.length; i++) {
7581 Intent intent = intents[i];
7582 if (intent != null) {
7583 if (intent.hasFileDescriptors()) {
7584 throw new IllegalArgumentException("File descriptors passed in Intent");
7586 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7587 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7588 throw new IllegalArgumentException(
7589 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7591 intents[i] = new Intent(intent);
7594 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7595 throw new IllegalArgumentException(
7596 "Intent array length does not match resolvedTypes length");
7599 if (bOptions != null) {
7600 if (bOptions.hasFileDescriptors()) {
7601 throw new IllegalArgumentException("File descriptors passed in options");
7605 synchronized(this) {
7606 int callingUid = Binder.getCallingUid();
7607 int origUserId = userId;
7608 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7609 type == ActivityManager.INTENT_SENDER_BROADCAST,
7610 ALLOW_NON_FULL, "getIntentSender", null);
7611 if (origUserId == UserHandle.USER_CURRENT) {
7612 // We don't want to evaluate this until the pending intent is
7613 // actually executed. However, we do want to always do the
7614 // security checking for it above.
7615 userId = UserHandle.USER_CURRENT;
7618 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7619 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7620 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7621 if (!UserHandle.isSameApp(callingUid, uid)) {
7622 String msg = "Permission Denial: getIntentSender() from pid="
7623 + Binder.getCallingPid()
7624 + ", uid=" + Binder.getCallingUid()
7625 + ", (need uid=" + uid + ")"
7626 + " is not allowed to send as package " + packageName;
7628 throw new SecurityException(msg);
7632 return getIntentSenderLocked(type, packageName, callingUid, userId,
7633 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7635 } catch (RemoteException e) {
7636 throw new SecurityException(e);
7641 IIntentSender getIntentSenderLocked(int type, String packageName,
7642 int callingUid, int userId, IBinder token, String resultWho,
7643 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7645 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7646 ActivityRecord activity = null;
7647 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7648 activity = ActivityRecord.isInStackLocked(token);
7649 if (activity == null) {
7650 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7653 if (activity.finishing) {
7654 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7659 // We're going to be splicing together extras before sending, so we're
7660 // okay poking into any contained extras.
7661 if (intents != null) {
7662 for (int i = 0; i < intents.length; i++) {
7663 intents[i].setDefusable(true);
7666 Bundle.setDefusable(bOptions, true);
7668 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7669 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7670 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7671 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7672 |PendingIntent.FLAG_UPDATE_CURRENT);
7674 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7675 type, packageName, activity, resultWho,
7676 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7677 WeakReference<PendingIntentRecord> ref;
7678 ref = mIntentSenderRecords.get(key);
7679 PendingIntentRecord rec = ref != null ? ref.get() : null;
7681 if (!cancelCurrent) {
7682 if (updateCurrent) {
7683 if (rec.key.requestIntent != null) {
7684 rec.key.requestIntent.replaceExtras(intents != null ?
7685 intents[intents.length - 1] : null);
7687 if (intents != null) {
7688 intents[intents.length-1] = rec.key.requestIntent;
7689 rec.key.allIntents = intents;
7690 rec.key.allResolvedTypes = resolvedTypes;
7692 rec.key.allIntents = null;
7693 rec.key.allResolvedTypes = null;
7698 makeIntentSenderCanceledLocked(rec);
7699 mIntentSenderRecords.remove(key);
7704 rec = new PendingIntentRecord(this, key, callingUid);
7705 mIntentSenderRecords.put(key, rec.ref);
7706 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7707 if (activity.pendingResults == null) {
7708 activity.pendingResults
7709 = new HashSet<WeakReference<PendingIntentRecord>>();
7711 activity.pendingResults.add(rec.ref);
7717 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7718 Intent intent, String resolvedType,
7719 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7720 if (target instanceof PendingIntentRecord) {
7721 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7722 whitelistToken, finishedReceiver, requiredPermission, options);
7724 if (intent == null) {
7725 // Weird case: someone has given us their own custom IIntentSender, and now
7726 // they have someone else trying to send to it but of course this isn't
7727 // really a PendingIntent, so there is no base Intent, and the caller isn't
7728 // supplying an Intent... but we never want to dispatch a null Intent to
7729 // a receiver, so um... let's make something up.
7730 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7731 intent = new Intent(Intent.ACTION_MAIN);
7734 target.send(code, intent, resolvedType, whitelistToken, null,
7735 requiredPermission, options);
7736 } catch (RemoteException e) {
7738 // Platform code can rely on getting a result back when the send is done, but if
7739 // this intent sender is from outside of the system we can't rely on it doing that.
7740 // So instead we don't give it the result receiver, and instead just directly
7741 // report the finish immediately.
7742 if (finishedReceiver != null) {
7744 finishedReceiver.performReceive(intent, 0,
7745 null, null, false, false, UserHandle.getCallingUserId());
7746 } catch (RemoteException e) {
7754 public void cancelIntentSender(IIntentSender sender) {
7755 if (!(sender instanceof PendingIntentRecord)) {
7758 synchronized(this) {
7759 PendingIntentRecord rec = (PendingIntentRecord)sender;
7761 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7762 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7763 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7764 String msg = "Permission Denial: cancelIntentSender() from pid="
7765 + Binder.getCallingPid()
7766 + ", uid=" + Binder.getCallingUid()
7767 + " is not allowed to cancel package "
7768 + rec.key.packageName;
7770 throw new SecurityException(msg);
7772 } catch (RemoteException e) {
7773 throw new SecurityException(e);
7775 cancelIntentSenderLocked(rec, true);
7779 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7780 makeIntentSenderCanceledLocked(rec);
7781 mIntentSenderRecords.remove(rec.key);
7782 if (cleanActivity && rec.key.activity != null) {
7783 rec.key.activity.pendingResults.remove(rec.ref);
7787 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7788 rec.canceled = true;
7789 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7790 if (callbacks != null) {
7791 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7796 public String getPackageForIntentSender(IIntentSender pendingResult) {
7797 if (!(pendingResult instanceof PendingIntentRecord)) {
7801 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7802 return res.key.packageName;
7803 } catch (ClassCastException e) {
7809 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7810 if (!(sender instanceof PendingIntentRecord)) {
7813 synchronized(this) {
7814 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7819 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7820 IResultReceiver receiver) {
7821 if (!(sender instanceof PendingIntentRecord)) {
7824 synchronized(this) {
7825 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7830 public int getUidForIntentSender(IIntentSender sender) {
7831 if (sender instanceof PendingIntentRecord) {
7833 PendingIntentRecord res = (PendingIntentRecord)sender;
7835 } catch (ClassCastException e) {
7842 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7843 if (!(pendingResult instanceof PendingIntentRecord)) {
7847 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7848 if (res.key.allIntents == null) {
7851 for (int i=0; i<res.key.allIntents.length; i++) {
7852 Intent intent = res.key.allIntents[i];
7853 if (intent.getPackage() != null && intent.getComponent() != null) {
7858 } catch (ClassCastException e) {
7864 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7865 if (!(pendingResult instanceof PendingIntentRecord)) {
7869 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7870 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7874 } catch (ClassCastException e) {
7880 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7881 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7882 "getIntentForIntentSender()");
7883 if (!(pendingResult instanceof PendingIntentRecord)) {
7887 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7888 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7889 } catch (ClassCastException e) {
7895 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7896 if (!(pendingResult instanceof PendingIntentRecord)) {
7900 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7901 synchronized (this) {
7902 return getTagForIntentSenderLocked(res, prefix);
7904 } catch (ClassCastException e) {
7909 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7910 final Intent intent = res.key.requestIntent;
7911 if (intent != null) {
7912 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7913 || res.lastTagPrefix.equals(prefix))) {
7916 res.lastTagPrefix = prefix;
7917 final StringBuilder sb = new StringBuilder(128);
7918 if (prefix != null) {
7921 if (intent.getAction() != null) {
7922 sb.append(intent.getAction());
7923 } else if (intent.getComponent() != null) {
7924 intent.getComponent().appendShortString(sb);
7928 return res.lastTag = sb.toString();
7934 public void setProcessLimit(int max) {
7935 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7936 "setProcessLimit()");
7937 synchronized (this) {
7938 mConstants.setOverrideMaxCachedProcesses(max);
7944 public int getProcessLimit() {
7945 synchronized (this) {
7946 return mConstants.getOverrideMaxCachedProcesses();
7950 void importanceTokenDied(ImportanceToken token) {
7951 synchronized (ActivityManagerService.this) {
7952 synchronized (mPidsSelfLocked) {
7954 = mImportantProcesses.get(token.pid);
7958 mImportantProcesses.remove(token.pid);
7959 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7963 pr.forcingToImportant = null;
7964 updateProcessForegroundLocked(pr, false, false);
7966 updateOomAdjLocked();
7971 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7972 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7973 "setProcessImportant()");
7974 synchronized(this) {
7975 boolean changed = false;
7977 synchronized (mPidsSelfLocked) {
7978 ProcessRecord pr = mPidsSelfLocked.get(pid);
7979 if (pr == null && isForeground) {
7980 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7983 ImportanceToken oldToken = mImportantProcesses.get(pid);
7984 if (oldToken != null) {
7985 oldToken.token.unlinkToDeath(oldToken, 0);
7986 mImportantProcesses.remove(pid);
7988 pr.forcingToImportant = null;
7992 if (isForeground && token != null) {
7993 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7995 public void binderDied() {
7996 importanceTokenDied(this);
8000 token.linkToDeath(newToken, 0);
8001 mImportantProcesses.put(pid, newToken);
8002 pr.forcingToImportant = newToken;
8004 } catch (RemoteException e) {
8005 // If the process died while doing this, we will later
8006 // do the cleanup with the process death link.
8012 updateOomAdjLocked();
8018 public boolean isAppForeground(int uid) throws RemoteException {
8019 synchronized (this) {
8020 UidRecord uidRec = mActiveUids.get(uid);
8021 if (uidRec == null || uidRec.idle) {
8024 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8028 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8029 // be guarded by permission checking.
8030 int getUidState(int uid) {
8031 synchronized (this) {
8032 return getUidStateLocked(uid);
8036 int getUidStateLocked(int uid) {
8037 UidRecord uidRec = mActiveUids.get(uid);
8038 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8042 public boolean isInMultiWindowMode(IBinder token) {
8043 final long origId = Binder.clearCallingIdentity();
8045 synchronized(this) {
8046 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8050 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8051 return !r.getTask().mFullscreen;
8054 Binder.restoreCallingIdentity(origId);
8059 public boolean isInPictureInPictureMode(IBinder token) {
8060 final long origId = Binder.clearCallingIdentity();
8062 synchronized(this) {
8063 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8066 Binder.restoreCallingIdentity(origId);
8070 private boolean isInPictureInPictureMode(ActivityRecord r) {
8071 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8072 r.getStack().isInStackLocked(r) == null) {
8076 // If we are animating to fullscreen then we have already dispatched the PIP mode
8077 // changed, so we should reflect that check here as well.
8078 final PinnedActivityStack stack = r.getStack();
8079 final PinnedStackWindowController windowController = stack.getWindowContainerController();
8080 return !windowController.isAnimatingBoundsToFullscreen();
8084 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8085 final long origId = Binder.clearCallingIdentity();
8087 synchronized(this) {
8088 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8089 "enterPictureInPictureMode", token, params);
8091 // If the activity is already in picture in picture mode, then just return early
8092 if (isInPictureInPictureMode(r)) {
8096 // Activity supports picture-in-picture, now check that we can enter PiP at this
8098 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8099 false /* beforeStopping */)) {
8103 final Runnable enterPipRunnable = () -> {
8104 // Only update the saved args from the args that are set
8105 r.pictureInPictureArgs.copyOnlySet(params);
8106 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8107 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8108 // Adjust the source bounds by the insets for the transition down
8109 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8110 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8111 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8112 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8113 stack.setPictureInPictureAspectRatio(aspectRatio);
8114 stack.setPictureInPictureActions(actions);
8116 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8117 r.supportsEnterPipOnTaskSwitch);
8118 logPictureInPictureArgs(params);
8121 if (isKeyguardLocked()) {
8122 // If the keyguard is showing or occluded, then try and dismiss it before
8123 // entering picture-in-picture (this will prompt the user to authenticate if the
8124 // device is currently locked).
8126 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8128 public void onDismissError() throws RemoteException {
8133 public void onDismissSucceeded() throws RemoteException {
8134 mHandler.post(enterPipRunnable);
8138 public void onDismissCancelled() throws RemoteException {
8142 } catch (RemoteException e) {
8146 // Enter picture in picture immediately otherwise
8147 enterPipRunnable.run();
8152 Binder.restoreCallingIdentity(origId);
8157 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8158 final long origId = Binder.clearCallingIdentity();
8160 synchronized(this) {
8161 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8162 "setPictureInPictureParams", token, params);
8164 // Only update the saved args from the args that are set
8165 r.pictureInPictureArgs.copyOnlySet(params);
8166 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8167 // If the activity is already in picture-in-picture, update the pinned stack now
8168 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8169 // be used the next time the activity enters PiP
8170 final PinnedActivityStack stack = r.getStack();
8171 if (!stack.isAnimatingBoundsToFullscreen()) {
8172 stack.setPictureInPictureAspectRatio(
8173 r.pictureInPictureArgs.getAspectRatio());
8174 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8177 logPictureInPictureArgs(params);
8180 Binder.restoreCallingIdentity(origId);
8185 public int getMaxNumPictureInPictureActions(IBinder token) {
8186 // Currently, this is a static constant, but later, we may change this to be dependent on
8187 // the context of the activity
8191 private void logPictureInPictureArgs(PictureInPictureParams params) {
8192 if (params.hasSetActions()) {
8193 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8194 params.getActions().size());
8196 if (params.hasSetAspectRatio()) {
8197 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8198 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8199 MetricsLogger.action(lm);
8204 * Checks the state of the system and the activity associated with the given {@param token} to
8205 * verify that picture-in-picture is supported for that activity.
8207 * @return the activity record for the given {@param token} if all the checks pass.
8209 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8210 IBinder token, PictureInPictureParams params) {
8211 if (!mSupportsPictureInPicture) {
8212 throw new IllegalStateException(caller
8213 + ": Device doesn't support picture-in-picture mode.");
8216 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8218 throw new IllegalStateException(caller
8219 + ": Can't find activity for token=" + token);
8222 if (!r.supportsPictureInPicture()) {
8223 throw new IllegalStateException(caller
8224 + ": Current activity does not support picture-in-picture.");
8227 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8228 throw new IllegalStateException(caller
8229 + ": Activities on the home, assistant, or recents stack not supported");
8232 if (params.hasSetAspectRatio()
8233 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8234 params.getAspectRatio())) {
8235 final float minAspectRatio = mContext.getResources().getFloat(
8236 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8237 final float maxAspectRatio = mContext.getResources().getFloat(
8238 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8239 throw new IllegalArgumentException(String.format(caller
8240 + ": Aspect ratio is too extreme (must be between %f and %f).",
8241 minAspectRatio, maxAspectRatio));
8244 // Truncate the number of actions if necessary
8245 params.truncateActions(getMaxNumPictureInPictureActions(token));
8250 // =========================================================
8252 // =========================================================
8254 static class ProcessInfoService extends IProcessInfoService.Stub {
8255 final ActivityManagerService mActivityManagerService;
8256 ProcessInfoService(ActivityManagerService activityManagerService) {
8257 mActivityManagerService = activityManagerService;
8261 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8262 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8263 /*in*/ pids, /*out*/ states, null);
8267 public void getProcessStatesAndOomScoresFromPids(
8268 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8269 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8270 /*in*/ pids, /*out*/ states, /*out*/ scores);
8275 * For each PID in the given input array, write the current process state
8276 * for that process into the states array, or -1 to indicate that no
8277 * process with the given PID exists. If scores array is provided, write
8278 * the oom score for the process into the scores array, with INVALID_ADJ
8279 * indicating the PID doesn't exist.
8281 public void getProcessStatesAndOomScoresForPIDs(
8282 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8283 if (scores != null) {
8284 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8285 "getProcessStatesAndOomScoresForPIDs()");
8289 throw new NullPointerException("pids");
8290 } else if (states == null) {
8291 throw new NullPointerException("states");
8292 } else if (pids.length != states.length) {
8293 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8294 } else if (scores != null && pids.length != scores.length) {
8295 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8298 synchronized (mPidsSelfLocked) {
8299 for (int i = 0; i < pids.length; i++) {
8300 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8301 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8303 if (scores != null) {
8304 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8310 // =========================================================
8312 // =========================================================
8314 static class PermissionController extends IPermissionController.Stub {
8315 ActivityManagerService mActivityManagerService;
8316 PermissionController(ActivityManagerService activityManagerService) {
8317 mActivityManagerService = activityManagerService;
8321 public boolean checkPermission(String permission, int pid, int uid) {
8322 return mActivityManagerService.checkPermission(permission, pid,
8323 uid) == PackageManager.PERMISSION_GRANTED;
8327 public String[] getPackagesForUid(int uid) {
8328 return mActivityManagerService.mContext.getPackageManager()
8329 .getPackagesForUid(uid);
8333 public boolean isRuntimePermission(String permission) {
8335 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8336 .getPermissionInfo(permission, 0);
8337 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8338 == PermissionInfo.PROTECTION_DANGEROUS;
8339 } catch (NameNotFoundException nnfe) {
8340 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8346 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8348 public int checkComponentPermission(String permission, int pid, int uid,
8349 int owningUid, boolean exported) {
8350 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8351 owningUid, exported);
8355 public Object getAMSLock() {
8356 return ActivityManagerService.this;
8361 * This can be called with or without the global lock held.
8363 int checkComponentPermission(String permission, int pid, int uid,
8364 int owningUid, boolean exported) {
8365 if (pid == MY_PID) {
8366 return PackageManager.PERMISSION_GRANTED;
8368 return ActivityManager.checkComponentPermission(permission, uid,
8369 owningUid, exported);
8373 * As the only public entry point for permissions checking, this method
8374 * can enforce the semantic that requesting a check on a null global
8375 * permission is automatically denied. (Internally a null permission
8376 * string is used when calling {@link #checkComponentPermission} in cases
8377 * when only uid-based security is needed.)
8379 * This can be called with or without the global lock held.
8382 public int checkPermission(String permission, int pid, int uid) {
8383 if (permission == null) {
8384 return PackageManager.PERMISSION_DENIED;
8386 return checkComponentPermission(permission, pid, uid, -1, true);
8390 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8391 if (permission == null) {
8392 return PackageManager.PERMISSION_DENIED;
8395 // We might be performing an operation on behalf of an indirect binder
8396 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8397 // client identity accordingly before proceeding.
8398 Identity tlsIdentity = sCallerIdentity.get();
8399 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8400 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8401 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8402 uid = tlsIdentity.uid;
8403 pid = tlsIdentity.pid;
8406 return checkComponentPermission(permission, pid, uid, -1, true);
8410 * Binder IPC calls go through the public entry point.
8411 * This can be called with or without the global lock held.
8413 int checkCallingPermission(String permission) {
8414 return checkPermission(permission,
8415 Binder.getCallingPid(),
8416 UserHandle.getAppId(Binder.getCallingUid()));
8420 * This can be called with or without the global lock held.
8422 void enforceCallingPermission(String permission, String func) {
8423 if (checkCallingPermission(permission)
8424 == PackageManager.PERMISSION_GRANTED) {
8428 String msg = "Permission Denial: " + func + " from pid="
8429 + Binder.getCallingPid()
8430 + ", uid=" + Binder.getCallingUid()
8431 + " requires " + permission;
8433 throw new SecurityException(msg);
8437 * Determine if UID is holding permissions required to access {@link Uri} in
8438 * the given {@link ProviderInfo}. Final permission checking is always done
8439 * in {@link ContentProvider}.
8441 private final boolean checkHoldingPermissionsLocked(
8442 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8443 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8444 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8445 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8446 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8447 != PERMISSION_GRANTED) {
8451 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8454 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8455 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8456 if (pi.applicationInfo.uid == uid) {
8458 } else if (!pi.exported) {
8462 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8463 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8465 // check if target holds top-level <provider> permissions
8466 if (!readMet && pi.readPermission != null && considerUidPermissions
8467 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8470 if (!writeMet && pi.writePermission != null && considerUidPermissions
8471 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8475 // track if unprotected read/write is allowed; any denied
8476 // <path-permission> below removes this ability
8477 boolean allowDefaultRead = pi.readPermission == null;
8478 boolean allowDefaultWrite = pi.writePermission == null;
8480 // check if target holds any <path-permission> that match uri
8481 final PathPermission[] pps = pi.pathPermissions;
8483 final String path = grantUri.uri.getPath();
8485 while (i > 0 && (!readMet || !writeMet)) {
8487 PathPermission pp = pps[i];
8488 if (pp.match(path)) {
8490 final String pprperm = pp.getReadPermission();
8491 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8492 "Checking read perm for " + pprperm + " for " + pp.getPath()
8493 + ": match=" + pp.match(path)
8494 + " check=" + pm.checkUidPermission(pprperm, uid));
8495 if (pprperm != null) {
8496 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8497 == PERMISSION_GRANTED) {
8500 allowDefaultRead = false;
8505 final String ppwperm = pp.getWritePermission();
8506 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8507 "Checking write perm " + ppwperm + " for " + pp.getPath()
8508 + ": match=" + pp.match(path)
8509 + " check=" + pm.checkUidPermission(ppwperm, uid));
8510 if (ppwperm != null) {
8511 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8512 == PERMISSION_GRANTED) {
8515 allowDefaultWrite = false;
8523 // grant unprotected <provider> read/write, if not blocked by
8524 // <path-permission> above
8525 if (allowDefaultRead) readMet = true;
8526 if (allowDefaultWrite) writeMet = true;
8528 } catch (RemoteException e) {
8532 return readMet && writeMet;
8535 public boolean isAppStartModeDisabled(int uid, String packageName) {
8536 synchronized (this) {
8537 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8538 == ActivityManager.APP_START_MODE_DISABLED;
8542 // Unified app-op and target sdk check
8543 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8544 // Apps that target O+ are always subject to background check
8545 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8546 if (DEBUG_BACKGROUND_CHECK) {
8547 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8549 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8551 // ...and legacy apps get an AppOp check
8552 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8554 if (DEBUG_BACKGROUND_CHECK) {
8555 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8558 case AppOpsManager.MODE_ALLOWED:
8559 return ActivityManager.APP_START_MODE_NORMAL;
8560 case AppOpsManager.MODE_IGNORED:
8561 return ActivityManager.APP_START_MODE_DELAYED;
8563 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8567 // Service launch is available to apps with run-in-background exemptions but
8568 // some other background operations are not. If we're doing a check
8569 // of service-launch policy, allow those callers to proceed unrestricted.
8570 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8572 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8573 if (DEBUG_BACKGROUND_CHECK) {
8574 Slog.i(TAG, "App " + uid + "/" + packageName
8575 + " is persistent; not restricted in background");
8577 return ActivityManager.APP_START_MODE_NORMAL;
8580 // Non-persistent but background whitelisted?
8581 if (uidOnBackgroundWhitelist(uid)) {
8582 if (DEBUG_BACKGROUND_CHECK) {
8583 Slog.i(TAG, "App " + uid + "/" + packageName
8584 + " on background whitelist; not restricted in background");
8586 return ActivityManager.APP_START_MODE_NORMAL;
8589 // Is this app on the battery whitelist?
8590 if (isOnDeviceIdleWhitelistLocked(uid)) {
8591 if (DEBUG_BACKGROUND_CHECK) {
8592 Slog.i(TAG, "App " + uid + "/" + packageName
8593 + " on idle whitelist; not restricted in background");
8595 return ActivityManager.APP_START_MODE_NORMAL;
8598 // None of the service-policy criteria apply, so we apply the common criteria
8599 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8602 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8603 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8604 UidRecord uidRec = mActiveUids.get(uid);
8605 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8606 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8607 + (uidRec != null ? uidRec.idle : false));
8608 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8610 if (uidRec == null) {
8611 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8612 UserHandle.getUserId(uid), packageName);
8614 ephemeral = uidRec.ephemeral;
8618 // We are hard-core about ephemeral apps not running in the background.
8619 return ActivityManager.APP_START_MODE_DISABLED;
8622 // The caller is only interested in whether app starts are completely
8623 // disabled for the given package (that is, it is an instant app). So
8624 // we don't need to go further, which is all just seeing if we should
8625 // apply a "delayed" mode for a regular app.
8626 return ActivityManager.APP_START_MODE_NORMAL;
8628 final int startMode = (alwaysRestrict)
8629 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8630 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8632 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8633 + " pkg=" + packageName + " startMode=" + startMode
8634 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8635 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8636 // This is an old app that has been forced into a "compatible as possible"
8637 // mode of background check. To increase compatibility, we will allow other
8638 // foreground apps to cause its services to start.
8639 if (callingPid >= 0) {
8641 synchronized (mPidsSelfLocked) {
8642 proc = mPidsSelfLocked.get(callingPid);
8645 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8646 // Whoever is instigating this is in the foreground, so we will allow it
8648 return ActivityManager.APP_START_MODE_NORMAL;
8655 return ActivityManager.APP_START_MODE_NORMAL;
8658 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8659 final int appId = UserHandle.getAppId(uid);
8660 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8661 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8662 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8665 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8666 ProviderInfo pi = null;
8667 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8672 pi = AppGlobals.getPackageManager().resolveContentProvider(
8673 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8675 } catch (RemoteException ex) {
8681 void grantEphemeralAccessLocked(int userId, Intent intent,
8682 int targetAppId, int ephemeralAppId) {
8683 getPackageManagerInternalLocked().
8684 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8687 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8688 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8689 if (targetUris != null) {
8690 return targetUris.get(grantUri);
8695 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8696 String targetPkg, int targetUid, GrantUri grantUri) {
8697 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8698 if (targetUris == null) {
8699 targetUris = Maps.newArrayMap();
8700 mGrantedUriPermissions.put(targetUid, targetUris);
8703 UriPermission perm = targetUris.get(grantUri);
8705 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8706 targetUris.put(grantUri, perm);
8712 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8713 final int modeFlags) {
8714 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8715 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8716 : UriPermission.STRENGTH_OWNED;
8718 // Root gets to do everything.
8723 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8724 if (perms == null) return false;
8726 // First look for exact match
8727 final UriPermission exactPerm = perms.get(grantUri);
8728 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8732 // No exact match, look for prefixes
8733 final int N = perms.size();
8734 for (int i = 0; i < N; i++) {
8735 final UriPermission perm = perms.valueAt(i);
8736 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8737 && perm.getStrength(modeFlags) >= minStrength) {
8746 * @param uri This uri must NOT contain an embedded userId.
8747 * @param userId The userId in which the uri is to be resolved.
8750 public int checkUriPermission(Uri uri, int pid, int uid,
8751 final int modeFlags, int userId, IBinder callerToken) {
8752 enforceNotIsolatedCaller("checkUriPermission");
8754 // Another redirected-binder-call permissions check as in
8755 // {@link checkPermissionWithToken}.
8756 Identity tlsIdentity = sCallerIdentity.get();
8757 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8758 uid = tlsIdentity.uid;
8759 pid = tlsIdentity.pid;
8762 // Our own process gets to do everything.
8763 if (pid == MY_PID) {
8764 return PackageManager.PERMISSION_GRANTED;
8766 synchronized (this) {
8767 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8768 ? PackageManager.PERMISSION_GRANTED
8769 : PackageManager.PERMISSION_DENIED;
8774 * Check if the targetPkg can be granted permission to access uri by
8775 * the callingUid using the given modeFlags. Throws a security exception
8776 * if callingUid is not allowed to do this. Returns the uid of the target
8777 * if the URI permission grant should be performed; returns -1 if it is not
8778 * needed (for example targetPkg already has permission to access the URI).
8779 * If you already know the uid of the target, you can supply it in
8780 * lastTargetUid else set that to -1.
8782 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8783 final int modeFlags, int lastTargetUid) {
8784 if (!Intent.isAccessUriMode(modeFlags)) {
8788 if (targetPkg != null) {
8789 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8790 "Checking grant " + targetPkg + " permission to " + grantUri);
8793 final IPackageManager pm = AppGlobals.getPackageManager();
8795 // If this is not a content: uri, we can't do anything with it.
8796 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8797 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8798 "Can't grant URI permission for non-content URI: " + grantUri);
8802 // Bail early if system is trying to hand out permissions directly; it
8803 // must always grant permissions on behalf of someone explicit.
8804 final int callingAppId = UserHandle.getAppId(callingUid);
8805 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8806 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8807 // Exempted authority for cropping user photos in Settings app
8809 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8810 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8815 final String authority = grantUri.uri.getAuthority();
8816 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8817 MATCH_DEBUG_TRIAGED_MISSING);
8819 Slog.w(TAG, "No content provider found for permission check: " +
8820 grantUri.uri.toSafeString());
8824 int targetUid = lastTargetUid;
8825 if (targetUid < 0 && targetPkg != null) {
8827 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8828 UserHandle.getUserId(callingUid));
8829 if (targetUid < 0) {
8830 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8831 "Can't grant URI permission no uid for: " + targetPkg);
8834 } catch (RemoteException ex) {
8839 // If we're extending a persistable grant, then we always need to create
8840 // the grant data structure so that take/release APIs work
8841 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8845 if (targetUid >= 0) {
8846 // First... does the target actually need this permission?
8847 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8848 // No need to grant the target this permission.
8849 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8850 "Target " + targetPkg + " already has full permission to " + grantUri);
8854 // First... there is no target package, so can anyone access it?
8855 boolean allowed = pi.exported;
8856 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8857 if (pi.readPermission != null) {
8861 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8862 if (pi.writePermission != null) {
8871 /* There is a special cross user grant if:
8872 * - The target is on another user.
8873 * - Apps on the current user can access the uri without any uid permissions.
8874 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8875 * grant uri permissions.
8877 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8878 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8879 modeFlags, false /*without considering the uid permissions*/);
8881 // Second... is the provider allowing granting of URI permissions?
8882 if (!specialCrossUserGrant) {
8883 if (!pi.grantUriPermissions) {
8884 throw new SecurityException("Provider " + pi.packageName
8886 + " does not allow granting of Uri permissions (uri "
8889 if (pi.uriPermissionPatterns != null) {
8890 final int N = pi.uriPermissionPatterns.length;
8891 boolean allowed = false;
8892 for (int i=0; i<N; i++) {
8893 if (pi.uriPermissionPatterns[i] != null
8894 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8900 throw new SecurityException("Provider " + pi.packageName
8902 + " does not allow granting of permission to path of Uri "
8908 // Third... does the caller itself have permission to access
8910 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8911 // Require they hold a strong enough Uri permission
8912 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8913 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8914 throw new SecurityException(
8915 "UID " + callingUid + " does not have permission to " + grantUri
8916 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8917 + "or related APIs");
8919 throw new SecurityException(
8920 "UID " + callingUid + " does not have permission to " + grantUri);
8928 * @param uri This uri must NOT contain an embedded userId.
8929 * @param userId The userId in which the uri is to be resolved.
8932 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8933 final int modeFlags, int userId) {
8934 enforceNotIsolatedCaller("checkGrantUriPermission");
8935 synchronized(this) {
8936 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8937 new GrantUri(userId, uri, false), modeFlags, -1);
8941 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8942 final int modeFlags, UriPermissionOwner owner) {
8943 if (!Intent.isAccessUriMode(modeFlags)) {
8947 // So here we are: the caller has the assumed permission
8948 // to the uri, and the target doesn't. Let's now give this to
8951 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8952 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8954 final String authority = grantUri.uri.getAuthority();
8955 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8956 MATCH_DEBUG_TRIAGED_MISSING);
8958 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8962 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8963 grantUri.prefix = true;
8965 final UriPermission perm = findOrCreateUriPermissionLocked(
8966 pi.packageName, targetPkg, targetUid, grantUri);
8967 perm.grantModes(modeFlags, owner);
8970 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8971 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8972 if (targetPkg == null) {
8973 throw new NullPointerException("targetPkg");
8976 final IPackageManager pm = AppGlobals.getPackageManager();
8978 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8979 } catch (RemoteException ex) {
8983 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8985 if (targetUid < 0) {
8989 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8993 static class NeededUriGrants extends ArrayList<GrantUri> {
8994 final String targetPkg;
8995 final int targetUid;
8998 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8999 this.targetPkg = targetPkg;
9000 this.targetUid = targetUid;
9006 * Like checkGrantUriPermissionLocked, but takes an Intent.
9008 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9009 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9010 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9011 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9012 + " clip=" + (intent != null ? intent.getClipData() : null)
9013 + " from " + intent + "; flags=0x"
9014 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9016 if (targetPkg == null) {
9017 throw new NullPointerException("targetPkg");
9020 if (intent == null) {
9023 Uri data = intent.getData();
9024 ClipData clip = intent.getClipData();
9025 if (data == null && clip == null) {
9028 // Default userId for uris in the intent (if they don't specify it themselves)
9029 int contentUserHint = intent.getContentUserHint();
9030 if (contentUserHint == UserHandle.USER_CURRENT) {
9031 contentUserHint = UserHandle.getUserId(callingUid);
9033 final IPackageManager pm = AppGlobals.getPackageManager();
9035 if (needed != null) {
9036 targetUid = needed.targetUid;
9039 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9041 } catch (RemoteException ex) {
9044 if (targetUid < 0) {
9045 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9046 "Can't grant URI permission no uid for: " + targetPkg
9047 + " on user " + targetUserId);
9052 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9053 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9055 if (targetUid > 0) {
9056 if (needed == null) {
9057 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9059 needed.add(grantUri);
9063 for (int i=0; i<clip.getItemCount(); i++) {
9064 Uri uri = clip.getItemAt(i).getUri();
9066 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9067 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9069 if (targetUid > 0) {
9070 if (needed == null) {
9071 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9073 needed.add(grantUri);
9076 Intent clipIntent = clip.getItemAt(i).getIntent();
9077 if (clipIntent != null) {
9078 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9079 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9080 if (newNeeded != null) {
9092 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9094 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9095 UriPermissionOwner owner) {
9096 if (needed != null) {
9097 for (int i=0; i<needed.size(); i++) {
9098 GrantUri grantUri = needed.get(i);
9099 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9100 grantUri, needed.flags, owner);
9105 void grantUriPermissionFromIntentLocked(int callingUid,
9106 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9107 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9108 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9109 if (needed == null) {
9113 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9117 * @param uri This uri must NOT contain an embedded userId.
9118 * @param userId The userId in which the uri is to be resolved.
9121 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9122 final int modeFlags, int userId) {
9123 enforceNotIsolatedCaller("grantUriPermission");
9124 GrantUri grantUri = new GrantUri(userId, uri, false);
9125 synchronized(this) {
9126 final ProcessRecord r = getRecordForAppLocked(caller);
9128 throw new SecurityException("Unable to find app for caller "
9130 + " when granting permission to uri " + grantUri);
9132 if (targetPkg == null) {
9133 throw new IllegalArgumentException("null target");
9135 if (grantUri == null) {
9136 throw new IllegalArgumentException("null uri");
9139 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9140 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9141 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9142 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9144 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9145 UserHandle.getUserId(r.uid));
9149 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9150 if (perm.modeFlags == 0) {
9151 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9153 if (perms != null) {
9154 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9155 "Removing " + perm.targetUid + " permission to " + perm.uri);
9157 perms.remove(perm.uri);
9158 if (perms.isEmpty()) {
9159 mGrantedUriPermissions.remove(perm.targetUid);
9165 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9166 final int modeFlags) {
9167 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9168 "Revoking all granted permissions to " + grantUri);
9170 final IPackageManager pm = AppGlobals.getPackageManager();
9171 final String authority = grantUri.uri.getAuthority();
9172 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9173 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9175 Slog.w(TAG, "No content provider found for permission revoke: "
9176 + grantUri.toSafeString());
9180 // Does the caller have this permission on the URI?
9181 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9182 // If they don't have direct access to the URI, then revoke any
9183 // ownerless URI permissions that have been granted to them.
9184 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9185 if (perms != null) {
9186 boolean persistChanged = false;
9187 for (int i = perms.size()-1; i >= 0; i--) {
9188 final UriPermission perm = perms.valueAt(i);
9189 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9192 if (perm.uri.sourceUserId == grantUri.sourceUserId
9193 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9194 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9195 "Revoking non-owned " + perm.targetUid
9196 + " permission to " + perm.uri);
9197 persistChanged |= perm.revokeModes(
9198 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9199 if (perm.modeFlags == 0) {
9204 if (perms.isEmpty()) {
9205 mGrantedUriPermissions.remove(callingUid);
9207 if (persistChanged) {
9208 schedulePersistUriGrants();
9214 boolean persistChanged = false;
9216 // Go through all of the permissions and remove any that match.
9217 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9218 final int targetUid = mGrantedUriPermissions.keyAt(i);
9219 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9221 for (int j = perms.size()-1; j >= 0; j--) {
9222 final UriPermission perm = perms.valueAt(j);
9223 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9226 if (perm.uri.sourceUserId == grantUri.sourceUserId
9227 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9228 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9229 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9230 persistChanged |= perm.revokeModes(
9231 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9232 targetPackage == null);
9233 if (perm.modeFlags == 0) {
9239 if (perms.isEmpty()) {
9240 mGrantedUriPermissions.removeAt(i);
9244 if (persistChanged) {
9245 schedulePersistUriGrants();
9250 * @param uri This uri must NOT contain an embedded userId.
9251 * @param userId The userId in which the uri is to be resolved.
9254 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9255 final int modeFlags, int userId) {
9256 enforceNotIsolatedCaller("revokeUriPermission");
9257 synchronized(this) {
9258 final ProcessRecord r = getRecordForAppLocked(caller);
9260 throw new SecurityException("Unable to find app for caller "
9262 + " when revoking permission to uri " + uri);
9265 Slog.w(TAG, "revokeUriPermission: null uri");
9269 if (!Intent.isAccessUriMode(modeFlags)) {
9273 final String authority = uri.getAuthority();
9274 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9275 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9277 Slog.w(TAG, "No content provider found for permission revoke: "
9278 + uri.toSafeString());
9282 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9288 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9291 * @param packageName Package name to match, or {@code null} to apply to all
9293 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9295 * @param persistable If persistable grants should be removed.
9297 private void removeUriPermissionsForPackageLocked(
9298 String packageName, int userHandle, boolean persistable) {
9299 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9300 throw new IllegalArgumentException("Must narrow by either package or user");
9303 boolean persistChanged = false;
9305 int N = mGrantedUriPermissions.size();
9306 for (int i = 0; i < N; i++) {
9307 final int targetUid = mGrantedUriPermissions.keyAt(i);
9308 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9310 // Only inspect grants matching user
9311 if (userHandle == UserHandle.USER_ALL
9312 || userHandle == UserHandle.getUserId(targetUid)) {
9313 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9314 final UriPermission perm = it.next();
9316 // Only inspect grants matching package
9317 if (packageName == null || perm.sourcePkg.equals(packageName)
9318 || perm.targetPkg.equals(packageName)) {
9319 // Hacky solution as part of fixing a security bug; ignore
9320 // grants associated with DownloadManager so we don't have
9321 // to immediately launch it to regrant the permissions
9322 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9323 && !persistable) continue;
9325 persistChanged |= perm.revokeModes(persistable
9326 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9328 // Only remove when no modes remain; any persisted grants
9329 // will keep this alive.
9330 if (perm.modeFlags == 0) {
9336 if (perms.isEmpty()) {
9337 mGrantedUriPermissions.remove(targetUid);
9344 if (persistChanged) {
9345 schedulePersistUriGrants();
9350 public IBinder newUriPermissionOwner(String name) {
9351 enforceNotIsolatedCaller("newUriPermissionOwner");
9352 synchronized(this) {
9353 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9354 return owner.getExternalTokenLocked();
9359 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9360 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9361 synchronized(this) {
9362 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9364 throw new IllegalArgumentException("Activity does not exist; token="
9367 return r.getUriPermissionsLocked().getExternalTokenLocked();
9371 * @param uri This uri must NOT contain an embedded userId.
9372 * @param sourceUserId The userId in which the uri is to be resolved.
9373 * @param targetUserId The userId of the app that receives the grant.
9376 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9377 final int modeFlags, int sourceUserId, int targetUserId) {
9378 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9379 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9380 "grantUriPermissionFromOwner", null);
9381 synchronized(this) {
9382 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9383 if (owner == null) {
9384 throw new IllegalArgumentException("Unknown owner: " + token);
9386 if (fromUid != Binder.getCallingUid()) {
9387 if (Binder.getCallingUid() != myUid()) {
9388 // Only system code can grant URI permissions on behalf
9390 throw new SecurityException("nice try");
9393 if (targetPkg == null) {
9394 throw new IllegalArgumentException("null target");
9397 throw new IllegalArgumentException("null uri");
9400 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9401 modeFlags, owner, targetUserId);
9406 * @param uri This uri must NOT contain an embedded userId.
9407 * @param userId The userId in which the uri is to be resolved.
9410 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9411 synchronized(this) {
9412 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9413 if (owner == null) {
9414 throw new IllegalArgumentException("Unknown owner: " + token);
9418 owner.removeUriPermissionsLocked(mode);
9420 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9421 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9426 private void schedulePersistUriGrants() {
9427 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9428 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9429 10 * DateUtils.SECOND_IN_MILLIS);
9433 private void writeGrantedUriPermissions() {
9434 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9436 // Snapshot permissions so we can persist without lock
9437 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9438 synchronized (this) {
9439 final int size = mGrantedUriPermissions.size();
9440 for (int i = 0; i < size; i++) {
9441 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9442 for (UriPermission perm : perms.values()) {
9443 if (perm.persistedModeFlags != 0) {
9444 persist.add(perm.snapshot());
9450 FileOutputStream fos = null;
9452 fos = mGrantFile.startWrite();
9454 XmlSerializer out = new FastXmlSerializer();
9455 out.setOutput(fos, StandardCharsets.UTF_8.name());
9456 out.startDocument(null, true);
9457 out.startTag(null, TAG_URI_GRANTS);
9458 for (UriPermission.Snapshot perm : persist) {
9459 out.startTag(null, TAG_URI_GRANT);
9460 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9461 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9462 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9463 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9464 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9465 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9466 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9467 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9468 out.endTag(null, TAG_URI_GRANT);
9470 out.endTag(null, TAG_URI_GRANTS);
9473 mGrantFile.finishWrite(fos);
9474 } catch (IOException e) {
9476 mGrantFile.failWrite(fos);
9481 private void readGrantedUriPermissionsLocked() {
9482 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9484 final long now = System.currentTimeMillis();
9486 FileInputStream fis = null;
9488 fis = mGrantFile.openRead();
9489 final XmlPullParser in = Xml.newPullParser();
9490 in.setInput(fis, StandardCharsets.UTF_8.name());
9493 while ((type = in.next()) != END_DOCUMENT) {
9494 final String tag = in.getName();
9495 if (type == START_TAG) {
9496 if (TAG_URI_GRANT.equals(tag)) {
9497 final int sourceUserId;
9498 final int targetUserId;
9499 final int userHandle = readIntAttribute(in,
9500 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9501 if (userHandle != UserHandle.USER_NULL) {
9502 // For backwards compatibility.
9503 sourceUserId = userHandle;
9504 targetUserId = userHandle;
9506 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9507 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9509 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9510 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9511 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9512 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9513 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9514 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9516 // Sanity check that provider still belongs to source package
9517 // Both direct boot aware and unaware packages are fine as we
9518 // will do filtering at query time to avoid multiple parsing.
9519 final ProviderInfo pi = getProviderInfoLocked(
9520 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9521 | MATCH_DIRECT_BOOT_UNAWARE);
9522 if (pi != null && sourcePkg.equals(pi.packageName)) {
9525 targetUid = AppGlobals.getPackageManager().getPackageUid(
9526 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9527 } catch (RemoteException e) {
9529 if (targetUid != -1) {
9530 final UriPermission perm = findOrCreateUriPermissionLocked(
9531 sourcePkg, targetPkg, targetUid,
9532 new GrantUri(sourceUserId, uri, prefix));
9533 perm.initPersistedModes(modeFlags, createdTime);
9536 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9537 + " but instead found " + pi);
9542 } catch (FileNotFoundException e) {
9543 // Missing grants is okay
9544 } catch (IOException e) {
9545 Slog.wtf(TAG, "Failed reading Uri grants", e);
9546 } catch (XmlPullParserException e) {
9547 Slog.wtf(TAG, "Failed reading Uri grants", e);
9549 IoUtils.closeQuietly(fis);
9554 * @param uri This uri must NOT contain an embedded userId.
9555 * @param userId The userId in which the uri is to be resolved.
9558 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9559 enforceNotIsolatedCaller("takePersistableUriPermission");
9561 Preconditions.checkFlagsArgument(modeFlags,
9562 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9564 synchronized (this) {
9565 final int callingUid = Binder.getCallingUid();
9566 boolean persistChanged = false;
9567 GrantUri grantUri = new GrantUri(userId, uri, false);
9569 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9570 new GrantUri(userId, uri, false));
9571 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9572 new GrantUri(userId, uri, true));
9574 final boolean exactValid = (exactPerm != null)
9575 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9576 final boolean prefixValid = (prefixPerm != null)
9577 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9579 if (!(exactValid || prefixValid)) {
9580 throw new SecurityException("No persistable permission grants found for UID "
9581 + callingUid + " and Uri " + grantUri.toSafeString());
9585 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9588 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9591 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9593 if (persistChanged) {
9594 schedulePersistUriGrants();
9600 * @param uri This uri must NOT contain an embedded userId.
9601 * @param userId The userId in which the uri is to be resolved.
9604 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9605 enforceNotIsolatedCaller("releasePersistableUriPermission");
9607 Preconditions.checkFlagsArgument(modeFlags,
9608 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9610 synchronized (this) {
9611 final int callingUid = Binder.getCallingUid();
9612 boolean persistChanged = false;
9614 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9615 new GrantUri(userId, uri, false));
9616 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9617 new GrantUri(userId, uri, true));
9618 if (exactPerm == null && prefixPerm == null) {
9619 throw new SecurityException("No permission grants found for UID " + callingUid
9620 + " and Uri " + uri.toSafeString());
9623 if (exactPerm != null) {
9624 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9625 removeUriPermissionIfNeededLocked(exactPerm);
9627 if (prefixPerm != null) {
9628 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9629 removeUriPermissionIfNeededLocked(prefixPerm);
9632 if (persistChanged) {
9633 schedulePersistUriGrants();
9639 * Prune any older {@link UriPermission} for the given UID until outstanding
9640 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9642 * @return if any mutations occured that require persisting.
9644 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9645 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9646 if (perms == null) return false;
9647 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9649 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9650 for (UriPermission perm : perms.values()) {
9651 if (perm.persistedModeFlags != 0) {
9652 persisted.add(perm);
9656 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9657 if (trimCount <= 0) return false;
9659 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9660 for (int i = 0; i < trimCount; i++) {
9661 final UriPermission perm = persisted.get(i);
9663 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9664 "Trimming grant created at " + perm.persistedCreateTime);
9666 perm.releasePersistableModes(~0);
9667 removeUriPermissionIfNeededLocked(perm);
9674 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9675 String packageName, boolean incoming) {
9676 enforceNotIsolatedCaller("getPersistedUriPermissions");
9677 Preconditions.checkNotNull(packageName, "packageName");
9679 final int callingUid = Binder.getCallingUid();
9680 final int callingUserId = UserHandle.getUserId(callingUid);
9681 final IPackageManager pm = AppGlobals.getPackageManager();
9683 final int packageUid = pm.getPackageUid(packageName,
9684 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9685 if (packageUid != callingUid) {
9686 throw new SecurityException(
9687 "Package " + packageName + " does not belong to calling UID " + callingUid);
9689 } catch (RemoteException e) {
9690 throw new SecurityException("Failed to verify package name ownership");
9693 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9694 synchronized (this) {
9696 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9698 if (perms == null) {
9699 Slog.w(TAG, "No permission grants found for " + packageName);
9701 for (UriPermission perm : perms.values()) {
9702 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9703 result.add(perm.buildPersistedPublicApiObject());
9708 final int size = mGrantedUriPermissions.size();
9709 for (int i = 0; i < size; i++) {
9710 final ArrayMap<GrantUri, UriPermission> perms =
9711 mGrantedUriPermissions.valueAt(i);
9712 for (UriPermission perm : perms.values()) {
9713 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9714 result.add(perm.buildPersistedPublicApiObject());
9720 return new ParceledListSlice<android.content.UriPermission>(result);
9724 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9725 String packageName, int userId) {
9726 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9727 "getGrantedUriPermissions");
9729 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9730 synchronized (this) {
9731 final int size = mGrantedUriPermissions.size();
9732 for (int i = 0; i < size; i++) {
9733 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9734 for (UriPermission perm : perms.values()) {
9735 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9736 && perm.persistedModeFlags != 0) {
9737 result.add(perm.buildPersistedPublicApiObject());
9742 return new ParceledListSlice<android.content.UriPermission>(result);
9746 public void clearGrantedUriPermissions(String packageName, int userId) {
9747 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9748 "clearGrantedUriPermissions");
9749 removeUriPermissionsForPackageLocked(packageName, userId, true);
9753 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9754 synchronized (this) {
9756 who != null ? getRecordForAppLocked(who) : null;
9757 if (app == null) return;
9759 Message msg = Message.obtain();
9760 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9762 msg.arg1 = waiting ? 1 : 0;
9763 mUiHandler.sendMessage(msg);
9768 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9769 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9770 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9771 outInfo.availMem = getFreeMemory();
9772 outInfo.totalMem = getTotalMemory();
9773 outInfo.threshold = homeAppMem;
9774 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9775 outInfo.hiddenAppThreshold = cachedAppMem;
9776 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9777 ProcessList.SERVICE_ADJ);
9778 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9779 ProcessList.VISIBLE_APP_ADJ);
9780 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9781 ProcessList.FOREGROUND_APP_ADJ);
9784 // =========================================================
9786 // =========================================================
9789 public List<IBinder> getAppTasks(String callingPackage) {
9790 int callingUid = Binder.getCallingUid();
9791 long ident = Binder.clearCallingIdentity();
9793 synchronized(this) {
9794 ArrayList<IBinder> list = new ArrayList<IBinder>();
9796 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9798 final int N = mRecentTasks.size();
9799 for (int i = 0; i < N; i++) {
9800 TaskRecord tr = mRecentTasks.get(i);
9801 // Skip tasks that do not match the caller. We don't need to verify
9802 // callingPackage, because we are also limiting to callingUid and know
9803 // that will limit to the correct security sandbox.
9804 if (tr.effectiveUid != callingUid) {
9807 Intent intent = tr.getBaseIntent();
9808 if (intent == null ||
9809 !callingPackage.equals(intent.getComponent().getPackageName())) {
9812 ActivityManager.RecentTaskInfo taskInfo =
9813 createRecentTaskInfoFromTaskRecord(tr);
9814 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9815 list.add(taskImpl.asBinder());
9818 Binder.restoreCallingIdentity(ident);
9825 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9826 final int callingUid = Binder.getCallingUid();
9827 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9829 synchronized(this) {
9830 if (DEBUG_ALL) Slog.v(
9831 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9833 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9836 // TODO: Improve with MRU list from all ActivityStacks.
9837 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9844 * Creates a new RecentTaskInfo from a TaskRecord.
9846 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9847 // Update the task description to reflect any changes in the task stack
9848 tr.updateTaskDescription();
9850 // Compose the recent task info
9851 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9852 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9853 rti.persistentId = tr.taskId;
9854 rti.baseIntent = new Intent(tr.getBaseIntent());
9855 rti.origActivity = tr.origActivity;
9856 rti.realActivity = tr.realActivity;
9857 rti.description = tr.lastDescription;
9858 rti.stackId = tr.getStackId();
9859 rti.userId = tr.userId;
9860 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9861 rti.firstActiveTime = tr.firstActiveTime;
9862 rti.lastActiveTime = tr.lastActiveTime;
9863 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9864 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9865 rti.numActivities = 0;
9866 if (tr.mBounds != null) {
9867 rti.bounds = new Rect(tr.mBounds);
9869 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9870 rti.resizeMode = tr.mResizeMode;
9872 ActivityRecord base = null;
9873 ActivityRecord top = null;
9876 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9877 tmp = tr.mActivities.get(i);
9878 if (tmp.finishing) {
9882 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9885 rti.numActivities++;
9888 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9889 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9894 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9895 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9896 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9898 if (checkPermission(android.Manifest.permission.GET_TASKS,
9899 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9900 // Temporary compatibility: some existing apps on the system image may
9901 // still be requesting the old permission and not switched to the new
9902 // one; if so, we'll still allow them full access. This means we need
9903 // to see if they are holding the old permission and are a system app.
9905 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9907 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9908 + " is using old GET_TASKS but privileged; allowing");
9910 } catch (RemoteException e) {
9915 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9916 + " does not hold REAL_GET_TASKS; limiting output");
9922 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9924 final int callingUid = Binder.getCallingUid();
9925 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9926 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9928 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9929 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9930 synchronized (this) {
9931 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9933 final boolean detailed = checkCallingPermission(
9934 android.Manifest.permission.GET_DETAILED_TASKS)
9935 == PackageManager.PERMISSION_GRANTED;
9937 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9938 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9939 return ParceledListSlice.emptyList();
9941 mRecentTasks.loadUserRecentsLocked(userId);
9943 final int recentsCount = mRecentTasks.size();
9944 ArrayList<ActivityManager.RecentTaskInfo> res =
9945 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9947 final Set<Integer> includedUsers;
9948 if (includeProfiles) {
9949 includedUsers = mUserController.getProfileIds(userId);
9951 includedUsers = new HashSet<>();
9953 includedUsers.add(Integer.valueOf(userId));
9955 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9956 TaskRecord tr = mRecentTasks.get(i);
9957 // Only add calling user or related users recent tasks
9958 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9959 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9963 if (tr.realActivitySuspended) {
9964 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9968 // Return the entry if desired by the caller. We always return
9969 // the first entry, because callers always expect this to be the
9970 // foreground app. We may filter others if the caller has
9971 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9972 // we should exclude the entry.
9976 || (tr.intent == null)
9977 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9980 // If the caller doesn't have the GET_TASKS permission, then only
9981 // allow them to see a small subset of tasks -- their own and home.
9982 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9983 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9987 final ActivityStack stack = tr.getStack();
9988 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9989 if (stack != null && stack.isHomeOrRecentsStack()) {
9990 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9991 "Skipping, home or recents stack task: " + tr);
9995 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9996 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9997 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9998 "Skipping, top task in docked stack: " + tr);
10002 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10003 if (stack != null && stack.isPinnedStack()) {
10004 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10005 "Skipping, pinned stack task: " + tr);
10009 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10010 // Don't include auto remove tasks that are finished or finishing.
10011 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10012 "Skipping, auto-remove without activity: " + tr);
10015 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10016 && !tr.isAvailable) {
10017 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10018 "Skipping, unavail real act: " + tr);
10022 if (!tr.mUserSetupComplete) {
10023 // Don't include task launched while user is not done setting-up.
10024 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10025 "Skipping, user setup not complete: " + tr);
10029 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10031 rti.baseIntent.replaceExtras((Bundle)null);
10038 return new ParceledListSlice<>(res);
10043 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10044 synchronized (this) {
10045 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10046 "getTaskThumbnail()");
10047 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10048 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10050 return tr.getTaskThumbnailLocked();
10057 public ActivityManager.TaskDescription getTaskDescription(int id) {
10058 synchronized (this) {
10059 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10060 "getTaskDescription()");
10061 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10062 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10064 return tr.lastTaskDescription;
10071 public int addAppTask(IBinder activityToken, Intent intent,
10072 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10073 final int callingUid = Binder.getCallingUid();
10074 final long callingIdent = Binder.clearCallingIdentity();
10077 synchronized (this) {
10078 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10080 throw new IllegalArgumentException("Activity does not exist; token="
10083 ComponentName comp = intent.getComponent();
10084 if (comp == null) {
10085 throw new IllegalArgumentException("Intent " + intent
10086 + " must specify explicit component");
10088 if (thumbnail.getWidth() != mThumbnailWidth
10089 || thumbnail.getHeight() != mThumbnailHeight) {
10090 throw new IllegalArgumentException("Bad thumbnail size: got "
10091 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10092 + mThumbnailWidth + "x" + mThumbnailHeight);
10094 if (intent.getSelector() != null) {
10095 intent.setSelector(null);
10097 if (intent.getSourceBounds() != null) {
10098 intent.setSourceBounds(null);
10100 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10101 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10102 // The caller has added this as an auto-remove task... that makes no
10103 // sense, so turn off auto-remove.
10104 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10107 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10108 mLastAddedTaskActivity = null;
10110 ActivityInfo ainfo = mLastAddedTaskActivity;
10111 if (ainfo == null) {
10112 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10113 comp, 0, UserHandle.getUserId(callingUid));
10114 if (ainfo.applicationInfo.uid != callingUid) {
10115 throw new SecurityException(
10116 "Can't add task for another application: target uid="
10117 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10121 TaskRecord task = new TaskRecord(this,
10122 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10123 ainfo, intent, description, new TaskThumbnailInfo());
10125 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10126 if (trimIdx >= 0) {
10127 // If this would have caused a trim, then we'll abort because that
10128 // means it would be added at the end of the list but then just removed.
10129 return INVALID_TASK_ID;
10132 final int N = mRecentTasks.size();
10133 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10134 final TaskRecord tr = mRecentTasks.remove(N - 1);
10135 tr.removedFromRecents();
10138 task.inRecents = true;
10139 mRecentTasks.add(task);
10140 r.getStack().addTask(task, false, "addAppTask");
10142 task.setLastThumbnailLocked(thumbnail);
10143 task.freeLastThumbnail();
10144 return task.taskId;
10147 Binder.restoreCallingIdentity(callingIdent);
10152 public Point getAppTaskThumbnailSize() {
10153 synchronized (this) {
10154 return new Point(mThumbnailWidth, mThumbnailHeight);
10159 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10160 synchronized (this) {
10161 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10163 r.setTaskDescription(td);
10164 final TaskRecord task = r.getTask();
10165 task.updateTaskDescription();
10166 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10172 public void setTaskResizeable(int taskId, int resizeableMode) {
10173 synchronized (this) {
10174 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10175 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10176 if (task == null) {
10177 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10180 task.setResizeMode(resizeableMode);
10185 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10186 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10187 long ident = Binder.clearCallingIdentity();
10189 synchronized (this) {
10190 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10191 if (task == null) {
10192 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10195 // Place the task in the right stack if it isn't there already based on
10196 // the requested bounds.
10197 // The stack transition logic is:
10198 // - a null bounds on a freeform task moves that task to fullscreen
10199 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10200 // that task to freeform
10201 // - otherwise the task is not moved
10202 int stackId = task.getStackId();
10203 if (!StackId.isTaskResizeAllowed(stackId)) {
10204 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10206 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10207 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10208 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10209 stackId = FREEFORM_WORKSPACE_STACK_ID;
10212 // Reparent the task to the right stack if necessary
10213 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10214 if (stackId != task.getStackId()) {
10215 // Defer resume until the task is resized below
10216 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10217 DEFER_RESUME, "resizeTask");
10218 preserveWindow = false;
10221 // After reparenting (which only resizes the task to the stack bounds), resize the
10222 // task to the actual bounds provided
10223 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10226 Binder.restoreCallingIdentity(ident);
10231 public Rect getTaskBounds(int taskId) {
10232 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10233 long ident = Binder.clearCallingIdentity();
10234 Rect rect = new Rect();
10236 synchronized (this) {
10237 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10238 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10239 if (task == null) {
10240 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10243 if (task.getStack() != null) {
10244 // Return the bounds from window manager since it will be adjusted for various
10245 // things like the presense of a docked stack for tasks that aren't resizeable.
10246 task.getWindowContainerBounds(rect);
10248 // Task isn't in window manager yet since it isn't associated with a stack.
10249 // Return the persist value from activity manager
10250 if (task.mBounds != null) {
10251 rect.set(task.mBounds);
10252 } else if (task.mLastNonFullscreenBounds != null) {
10253 rect.set(task.mLastNonFullscreenBounds);
10258 Binder.restoreCallingIdentity(ident);
10264 public void cancelTaskWindowTransition(int taskId) {
10265 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10266 final long ident = Binder.clearCallingIdentity();
10268 synchronized (this) {
10269 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10270 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10271 if (task == null) {
10272 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10275 task.cancelWindowTransition();
10278 Binder.restoreCallingIdentity(ident);
10283 public void cancelTaskThumbnailTransition(int taskId) {
10284 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10285 final long ident = Binder.clearCallingIdentity();
10287 synchronized (this) {
10288 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10289 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10290 if (task == null) {
10291 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10294 task.cancelThumbnailTransition();
10297 Binder.restoreCallingIdentity(ident);
10302 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10303 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10304 final long ident = Binder.clearCallingIdentity();
10306 final TaskRecord task;
10307 synchronized (this) {
10308 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10309 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10310 if (task == null) {
10311 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10315 // Don't call this while holding the lock as this operation might hit the disk.
10316 return task.getSnapshot(reducedResolution);
10318 Binder.restoreCallingIdentity(ident);
10323 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10324 if (userId != UserHandle.getCallingUserId()) {
10325 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10326 "getTaskDescriptionIcon");
10328 final File passedIconFile = new File(filePath);
10329 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10330 passedIconFile.getName());
10331 if (!legitIconFile.getPath().equals(filePath)
10332 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10333 throw new IllegalArgumentException("Bad file path: " + filePath
10334 + " passed for userId " + userId);
10336 return mRecentTasks.getTaskDescriptionIcon(filePath);
10340 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10341 throws RemoteException {
10342 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10343 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10344 activityOptions.getCustomInPlaceResId() == 0) {
10345 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10346 "with valid animation");
10348 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10349 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10350 activityOptions.getCustomInPlaceResId());
10351 mWindowManager.executeAppTransition();
10354 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10355 // Remove all tasks with activities in the specified package from the list of recent tasks
10356 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10357 TaskRecord tr = mRecentTasks.get(i);
10358 if (tr.userId != userId) continue;
10360 ComponentName cn = tr.intent.getComponent();
10361 if (cn != null && cn.getPackageName().equals(packageName)) {
10362 // If the package name matches, remove the task.
10363 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10368 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10371 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10372 TaskRecord tr = mRecentTasks.get(i);
10373 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10377 ComponentName cn = tr.intent.getComponent();
10378 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10379 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10380 if (sameComponent) {
10381 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10387 public void removeStack(int stackId) {
10388 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10389 if (StackId.isHomeOrRecentsStack(stackId)) {
10390 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10393 synchronized (this) {
10394 final long ident = Binder.clearCallingIdentity();
10396 mStackSupervisor.removeStackLocked(stackId);
10398 Binder.restoreCallingIdentity(ident);
10404 public void moveStackToDisplay(int stackId, int displayId) {
10405 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10407 synchronized (this) {
10408 final long ident = Binder.clearCallingIdentity();
10410 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10411 + " to displayId=" + displayId);
10412 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10414 Binder.restoreCallingIdentity(ident);
10420 public boolean removeTask(int taskId) {
10421 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10422 synchronized (this) {
10423 final long ident = Binder.clearCallingIdentity();
10425 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10427 Binder.restoreCallingIdentity(ident);
10433 * TODO: Add mController hook
10436 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10437 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10439 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10440 synchronized(this) {
10441 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10445 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10446 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10448 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10449 Binder.getCallingUid(), -1, -1, "Task to front")) {
10450 ActivityOptions.abort(options);
10453 final long origId = Binder.clearCallingIdentity();
10455 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10456 if (task == null) {
10457 Slog.d(TAG, "Could not find task for id: "+ taskId);
10460 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10461 mStackSupervisor.showLockTaskToast();
10462 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10465 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10466 if (prev != null) {
10467 task.setTaskToReturnTo(prev);
10469 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10470 false /* forceNonResizable */);
10472 final ActivityRecord topActivity = task.getTopActivity();
10473 if (topActivity != null) {
10475 // We are reshowing a task, use a starting window to hide the initial draw delay
10476 // so the transition can start earlier.
10477 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10478 true /* taskSwitch */, fromRecents);
10481 Binder.restoreCallingIdentity(origId);
10483 ActivityOptions.abort(options);
10487 * Attempts to move a task backwards in z-order (the order of activities within the task is
10490 * There are several possible results of this call:
10491 * - if the task is locked, then we will show the lock toast
10492 * - if there is a task behind the provided task, then that task is made visible and resumed as
10493 * this task is moved to the back
10494 * - otherwise, if there are no other tasks in the stack:
10495 * - if this task is in the pinned stack, then we remove the stack completely, which will
10496 * have the effect of moving the task to the top or bottom of the fullscreen stack
10497 * (depending on whether it is visible)
10498 * - otherwise, we simply return home and hide this task
10500 * @param token A reference to the activity we wish to move
10501 * @param nonRoot If false then this only works if the activity is the root
10502 * of a task; if true it will work for any activity in a task.
10503 * @return Returns true if the move completed, false if not.
10506 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10507 enforceNotIsolatedCaller("moveActivityTaskToBack");
10508 synchronized(this) {
10509 final long origId = Binder.clearCallingIdentity();
10511 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10512 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10513 if (task != null) {
10514 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10517 Binder.restoreCallingIdentity(origId);
10524 public void moveTaskBackwards(int task) {
10525 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10526 "moveTaskBackwards()");
10528 synchronized(this) {
10529 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10530 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10533 final long origId = Binder.clearCallingIdentity();
10534 moveTaskBackwardsLocked(task);
10535 Binder.restoreCallingIdentity(origId);
10539 private final void moveTaskBackwardsLocked(int task) {
10540 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10544 public int createStackOnDisplay(int displayId) throws RemoteException {
10545 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10546 synchronized (this) {
10547 final int stackId = mStackSupervisor.getNextStackId();
10548 final ActivityStack stack =
10549 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10550 if (stack == null) {
10551 return INVALID_STACK_ID;
10553 return stack.mStackId;
10558 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10559 synchronized (this) {
10560 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10561 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10562 return stack.mDisplayId;
10564 return DEFAULT_DISPLAY;
10569 public int getActivityStackId(IBinder token) throws RemoteException {
10570 synchronized (this) {
10571 ActivityStack stack = ActivityRecord.getStackLocked(token);
10572 if (stack == null) {
10573 return INVALID_STACK_ID;
10575 return stack.mStackId;
10580 public void exitFreeformMode(IBinder token) throws RemoteException {
10581 synchronized (this) {
10582 long ident = Binder.clearCallingIdentity();
10584 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10586 throw new IllegalArgumentException(
10587 "exitFreeformMode: No activity record matching token=" + token);
10590 final ActivityStack stack = r.getStack();
10591 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10592 throw new IllegalStateException(
10593 "exitFreeformMode: You can only go fullscreen from freeform.");
10596 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10597 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10598 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10600 Binder.restoreCallingIdentity(ident);
10606 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10607 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10608 if (StackId.isHomeOrRecentsStack(stackId)) {
10609 throw new IllegalArgumentException(
10610 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10612 synchronized (this) {
10613 long ident = Binder.clearCallingIdentity();
10615 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10616 if (task == null) {
10617 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10621 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10622 + " to stackId=" + stackId + " toTop=" + toTop);
10623 if (stackId == DOCKED_STACK_ID) {
10624 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10625 null /* initialBounds */);
10627 task.reparent(stackId, toTop,
10628 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10630 Binder.restoreCallingIdentity(ident);
10636 public void swapDockedAndFullscreenStack() throws RemoteException {
10637 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10638 synchronized (this) {
10639 long ident = Binder.clearCallingIdentity();
10641 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10642 FULLSCREEN_WORKSPACE_STACK_ID);
10643 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10645 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10646 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10648 if (topTask == null || tasks == null || tasks.size() == 0) {
10650 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10654 // TODO: App transition
10655 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10657 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10658 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10659 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10660 final int size = tasks.size();
10661 for (int i = 0; i < size; i++) {
10662 final int id = tasks.get(i).taskId;
10663 if (id == topTask.taskId) {
10667 // Defer the resume until after all the tasks have been moved
10668 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10669 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10670 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10673 // Because we deferred the resume to avoid conflicts with stack switches while
10674 // resuming, we need to do it after all the tasks are moved.
10675 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10676 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10678 mWindowManager.executeAppTransition();
10680 Binder.restoreCallingIdentity(ident);
10686 * Moves the input task to the docked stack.
10688 * @param taskId Id of task to move.
10689 * @param createMode The mode the docked stack should be created in if it doesn't exist
10691 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10693 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10694 * @param toTop If the task and stack should be moved to the top.
10695 * @param animate Whether we should play an animation for the moving the task
10696 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10697 * docked stack. Pass {@code null} to use default bounds.
10700 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10701 Rect initialBounds) {
10702 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10703 synchronized (this) {
10704 long ident = Binder.clearCallingIdentity();
10706 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10707 if (task == null) {
10708 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10712 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10713 + " to createMode=" + createMode + " toTop=" + toTop);
10714 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10716 // Defer resuming until we move the home stack to the front below
10717 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10718 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10719 "moveTaskToDockedStack");
10721 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10725 Binder.restoreCallingIdentity(ident);
10731 * Moves the top activity in the input stackId to the pinned stack.
10733 * @param stackId Id of stack to move the top activity to pinned stack.
10734 * @param bounds Bounds to use for pinned stack.
10736 * @return True if the top activity of the input stack was successfully moved to the pinned
10740 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10741 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10742 synchronized (this) {
10743 if (!mSupportsPictureInPicture) {
10744 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10745 + "Device doesn't support picture-in-picture mode");
10748 long ident = Binder.clearCallingIdentity();
10750 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10752 Binder.restoreCallingIdentity(ident);
10758 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10759 boolean preserveWindows, boolean animate, int animationDuration) {
10760 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10761 long ident = Binder.clearCallingIdentity();
10763 synchronized (this) {
10765 if (stackId == PINNED_STACK_ID) {
10766 final PinnedActivityStack pinnedStack =
10767 mStackSupervisor.getStack(PINNED_STACK_ID);
10768 if (pinnedStack != null) {
10769 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10770 destBounds, animationDuration, false /* fromFullscreen */);
10773 throw new IllegalArgumentException("Stack: " + stackId
10774 + " doesn't support animated resize.");
10777 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10778 null /* tempTaskInsetBounds */, preserveWindows,
10779 allowResizeInDockedMode, !DEFER_RESUME);
10783 Binder.restoreCallingIdentity(ident);
10788 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10789 Rect tempDockedTaskInsetBounds,
10790 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10791 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10792 "resizeDockedStack()");
10793 long ident = Binder.clearCallingIdentity();
10795 synchronized (this) {
10796 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10797 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10801 Binder.restoreCallingIdentity(ident);
10806 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10807 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10808 "resizePinnedStack()");
10809 final long ident = Binder.clearCallingIdentity();
10811 synchronized (this) {
10812 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10815 Binder.restoreCallingIdentity(ident);
10820 * Try to place task to provided position. The final position might be different depending on
10821 * current user and stacks state. The task will be moved to target stack if it's currently in
10825 public void positionTaskInStack(int taskId, int stackId, int position) {
10826 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10827 if (StackId.isHomeOrRecentsStack(stackId)) {
10828 throw new IllegalArgumentException(
10829 "positionTaskInStack: Attempt to change the position of task "
10830 + taskId + " in/to home/recents stack");
10832 synchronized (this) {
10833 long ident = Binder.clearCallingIdentity();
10835 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10836 + taskId + " in stackId=" + stackId + " at position=" + position);
10837 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10838 if (task == null) {
10839 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10843 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10846 // TODO: Have the callers of this API call a separate reparent method if that is
10847 // what they intended to do vs. having this method also do reparenting.
10848 if (task.getStack() == stack) {
10849 // Change position in current stack.
10850 stack.positionChildAt(task, position);
10852 // Reparent to new stack.
10853 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10854 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10857 Binder.restoreCallingIdentity(ident);
10863 public List<StackInfo> getAllStackInfos() {
10864 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10865 long ident = Binder.clearCallingIdentity();
10867 synchronized (this) {
10868 return mStackSupervisor.getAllStackInfosLocked();
10871 Binder.restoreCallingIdentity(ident);
10876 public StackInfo getStackInfo(int stackId) {
10877 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10878 long ident = Binder.clearCallingIdentity();
10880 synchronized (this) {
10881 return mStackSupervisor.getStackInfoLocked(stackId);
10884 Binder.restoreCallingIdentity(ident);
10889 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10890 synchronized(this) {
10891 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10896 public void updateDeviceOwner(String packageName) {
10897 final int callingUid = Binder.getCallingUid();
10898 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10899 throw new SecurityException("updateDeviceOwner called from non-system process");
10901 synchronized (this) {
10902 mDeviceOwnerName = packageName;
10907 public void updateLockTaskPackages(int userId, String[] packages) {
10908 final int callingUid = Binder.getCallingUid();
10909 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10910 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10911 "updateLockTaskPackages()");
10913 synchronized (this) {
10914 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10915 Arrays.toString(packages));
10916 mLockTaskPackages.put(userId, packages);
10917 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10922 void startLockTaskModeLocked(TaskRecord task) {
10923 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10924 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10928 // When a task is locked, dismiss the pinned stack if it exists
10929 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10931 if (pinnedStack != null) {
10932 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10935 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10936 // is initiated by system after the pinning request was shown and locked mode is initiated
10937 // by an authorized app directly
10938 final int callingUid = Binder.getCallingUid();
10939 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10940 long ident = Binder.clearCallingIdentity();
10942 if (!isSystemInitiated) {
10943 task.mLockTaskUid = callingUid;
10944 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10945 // startLockTask() called by app and task mode is lockTaskModeDefault.
10946 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10947 StatusBarManagerInternal statusBarManager =
10948 LocalServices.getService(StatusBarManagerInternal.class);
10949 if (statusBarManager != null) {
10950 statusBarManager.showScreenPinningRequest(task.taskId);
10955 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10956 if (stack == null || task != stack.topTask()) {
10957 throw new IllegalArgumentException("Invalid task, not in foreground");
10960 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10962 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10963 ActivityManager.LOCK_TASK_MODE_PINNED :
10964 ActivityManager.LOCK_TASK_MODE_LOCKED,
10965 "startLockTask", true);
10967 Binder.restoreCallingIdentity(ident);
10972 public void startLockTaskModeById(int taskId) {
10973 synchronized (this) {
10974 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10975 if (task != null) {
10976 startLockTaskModeLocked(task);
10982 public void startLockTaskModeByToken(IBinder token) {
10983 synchronized (this) {
10984 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10988 final TaskRecord task = r.getTask();
10989 if (task != null) {
10990 startLockTaskModeLocked(task);
10996 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10997 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10998 // This makes inner call to look as if it was initiated by system.
10999 long ident = Binder.clearCallingIdentity();
11001 synchronized (this) {
11002 startLockTaskModeById(taskId);
11005 Binder.restoreCallingIdentity(ident);
11010 public void stopLockTaskMode() {
11011 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11012 if (lockTask == null) {
11013 // Our work here is done.
11017 final int callingUid = Binder.getCallingUid();
11018 final int lockTaskUid = lockTask.mLockTaskUid;
11019 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11020 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11024 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11025 // It is possible lockTaskMode was started by the system process because
11026 // android:lockTaskMode is set to a locking value in the application manifest
11027 // instead of the app calling startLockTaskMode. In this case
11028 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11029 // {@link TaskRecord.effectiveUid} instead. Also caller with
11030 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11031 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11032 && callingUid != lockTaskUid
11033 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11034 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11035 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11038 long ident = Binder.clearCallingIdentity();
11040 Log.d(TAG, "stopLockTaskMode");
11042 synchronized (this) {
11043 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11044 "stopLockTask", true);
11046 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11048 tm.showInCallScreen(false);
11051 Binder.restoreCallingIdentity(ident);
11056 * This API should be called by SystemUI only when user perform certain action to dismiss
11057 * lock task mode. We should only dismiss pinned lock task mode in this case.
11060 public void stopSystemLockTaskMode() throws RemoteException {
11061 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11062 stopLockTaskMode();
11064 mStackSupervisor.showLockTaskToast();
11069 public boolean isInLockTaskMode() {
11070 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11074 public int getLockTaskModeState() {
11075 synchronized (this) {
11076 return mStackSupervisor.getLockTaskModeState();
11081 public void showLockTaskEscapeMessage(IBinder token) {
11082 synchronized (this) {
11083 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11087 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11092 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11093 throws RemoteException {
11094 synchronized (this) {
11095 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11097 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11101 final long origId = Binder.clearCallingIdentity();
11103 r.setDisablePreviewScreenshots(disable);
11105 Binder.restoreCallingIdentity(origId);
11110 // =========================================================
11111 // CONTENT PROVIDERS
11112 // =========================================================
11114 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11115 List<ProviderInfo> providers = null;
11117 providers = AppGlobals.getPackageManager()
11118 .queryContentProviders(app.processName, app.uid,
11119 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11120 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11122 } catch (RemoteException ex) {
11124 if (DEBUG_MU) Slog.v(TAG_MU,
11125 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11126 int userId = app.userId;
11127 if (providers != null) {
11128 int N = providers.size();
11129 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11130 for (int i=0; i<N; i++) {
11131 // TODO: keep logic in sync with installEncryptionUnawareProviders
11133 (ProviderInfo)providers.get(i);
11134 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11135 cpi.name, cpi.flags);
11136 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11137 // This is a singleton provider, but a user besides the
11138 // default user is asking to initialize a process it runs
11139 // in... well, no, it doesn't actually run in this process,
11140 // it runs in the process of the default user. Get rid of it.
11141 providers.remove(i);
11147 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11148 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11150 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11151 mProviderMap.putProviderByClass(comp, cpr);
11153 if (DEBUG_MU) Slog.v(TAG_MU,
11154 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11155 app.pubProviders.put(cpi.name, cpr);
11156 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11157 // Don't add this if it is a platform component that is marked
11158 // to run in multiple processes, because this is actually
11159 // part of the framework so doesn't make sense to track as a
11160 // separate apk in the process.
11161 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11164 notifyPackageUse(cpi.applicationInfo.packageName,
11165 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11172 * Check if the calling UID has a possible chance at accessing the provider
11173 * at the given authority and user.
11175 public String checkContentProviderAccess(String authority, int userId) {
11176 if (userId == UserHandle.USER_ALL) {
11177 mContext.enforceCallingOrSelfPermission(
11178 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11179 userId = UserHandle.getCallingUserId();
11182 ProviderInfo cpi = null;
11184 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11185 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11186 | PackageManager.MATCH_DISABLED_COMPONENTS
11187 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11188 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11190 } catch (RemoteException ignored) {
11193 return "Failed to find provider " + authority + " for user " + userId
11194 + "; expected to find a valid ContentProvider for this authority";
11197 ProcessRecord r = null;
11198 synchronized (mPidsSelfLocked) {
11199 r = mPidsSelfLocked.get(Binder.getCallingPid());
11202 return "Failed to find PID " + Binder.getCallingPid();
11205 synchronized (this) {
11206 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11211 * Check if {@link ProcessRecord} has a possible chance at accessing the
11212 * given {@link ProviderInfo}. Final permission checking is always done
11213 * in {@link ContentProvider}.
11215 private final String checkContentProviderPermissionLocked(
11216 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11217 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11218 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11219 boolean checkedGrants = false;
11221 // Looking for cross-user grants before enforcing the typical cross-users permissions
11222 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11223 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11224 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11227 checkedGrants = true;
11229 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11230 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11231 if (userId != tmpTargetUserId) {
11232 // When we actually went to determine the final targer user ID, this ended
11233 // up different than our initial check for the authority. This is because
11234 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11235 // SELF. So we need to re-check the grants again.
11236 checkedGrants = false;
11239 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11240 cpi.applicationInfo.uid, cpi.exported)
11241 == PackageManager.PERMISSION_GRANTED) {
11244 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11245 cpi.applicationInfo.uid, cpi.exported)
11246 == PackageManager.PERMISSION_GRANTED) {
11250 PathPermission[] pps = cpi.pathPermissions;
11252 int i = pps.length;
11255 PathPermission pp = pps[i];
11256 String pprperm = pp.getReadPermission();
11257 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11258 cpi.applicationInfo.uid, cpi.exported)
11259 == PackageManager.PERMISSION_GRANTED) {
11262 String ppwperm = pp.getWritePermission();
11263 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11264 cpi.applicationInfo.uid, cpi.exported)
11265 == PackageManager.PERMISSION_GRANTED) {
11270 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11274 final String suffix;
11275 if (!cpi.exported) {
11276 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11277 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11278 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11280 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11282 final String msg = "Permission Denial: opening provider " + cpi.name
11283 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11284 + ", uid=" + callingUid + ")" + suffix;
11290 * Returns if the ContentProvider has granted a uri to callingUid
11292 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11293 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11294 if (perms != null) {
11295 for (int i=perms.size()-1; i>=0; i--) {
11296 GrantUri grantUri = perms.keyAt(i);
11297 if (grantUri.sourceUserId == userId || !checkUser) {
11298 if (matchesProvider(grantUri.uri, cpi)) {
11308 * Returns true if the uri authority is one of the authorities specified in the provider.
11310 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11311 String uriAuth = uri.getAuthority();
11312 String cpiAuth = cpi.authority;
11313 if (cpiAuth.indexOf(';') == -1) {
11314 return cpiAuth.equals(uriAuth);
11316 String[] cpiAuths = cpiAuth.split(";");
11317 int length = cpiAuths.length;
11318 for (int i = 0; i < length; i++) {
11319 if (cpiAuths[i].equals(uriAuth)) return true;
11324 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11325 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11327 for (int i=0; i<r.conProviders.size(); i++) {
11328 ContentProviderConnection conn = r.conProviders.get(i);
11329 if (conn.provider == cpr) {
11330 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11331 "Adding provider requested by "
11332 + r.processName + " from process "
11333 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11334 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11336 conn.stableCount++;
11337 conn.numStableIncs++;
11339 conn.unstableCount++;
11340 conn.numUnstableIncs++;
11345 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11347 conn.stableCount = 1;
11348 conn.numStableIncs = 1;
11350 conn.unstableCount = 1;
11351 conn.numUnstableIncs = 1;
11353 cpr.connections.add(conn);
11354 r.conProviders.add(conn);
11355 startAssociationLocked(r.uid, r.processName, r.curProcState,
11356 cpr.uid, cpr.name, cpr.info.processName);
11359 cpr.addExternalProcessHandleLocked(externalProcessToken);
11363 boolean decProviderCountLocked(ContentProviderConnection conn,
11364 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11365 if (conn != null) {
11366 cpr = conn.provider;
11367 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11368 "Removing provider requested by "
11369 + conn.client.processName + " from process "
11370 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11371 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11373 conn.stableCount--;
11375 conn.unstableCount--;
11377 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11378 cpr.connections.remove(conn);
11379 conn.client.conProviders.remove(conn);
11380 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11381 // The client is more important than last activity -- note the time this
11382 // is happening, so we keep the old provider process around a bit as last
11383 // activity to avoid thrashing it.
11384 if (cpr.proc != null) {
11385 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11388 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11393 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11397 private void checkTime(long startTime, String where) {
11398 long now = SystemClock.uptimeMillis();
11399 if ((now-startTime) > 50) {
11400 // If we are taking more than 50ms, log about it.
11401 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11405 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11407 PROC_SPACE_TERM|PROC_PARENS,
11408 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11411 private final long[] mProcessStateStatsLongs = new long[1];
11413 boolean isProcessAliveLocked(ProcessRecord proc) {
11414 if (proc.procStatFile == null) {
11415 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11417 mProcessStateStatsLongs[0] = 0;
11418 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11419 mProcessStateStatsLongs, null)) {
11420 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11423 final long state = mProcessStateStatsLongs[0];
11424 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11426 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11429 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11430 String name, IBinder token, boolean stable, int userId) {
11431 ContentProviderRecord cpr;
11432 ContentProviderConnection conn = null;
11433 ProviderInfo cpi = null;
11435 synchronized(this) {
11436 long startTime = SystemClock.uptimeMillis();
11438 ProcessRecord r = null;
11439 if (caller != null) {
11440 r = getRecordForAppLocked(caller);
11442 throw new SecurityException(
11443 "Unable to find app for caller " + caller
11444 + " (pid=" + Binder.getCallingPid()
11445 + ") when getting content provider " + name);
11449 boolean checkCrossUser = true;
11451 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11453 // First check if this content provider has been published...
11454 cpr = mProviderMap.getProviderByName(name, userId);
11455 // If that didn't work, check if it exists for user 0 and then
11456 // verify that it's a singleton provider before using it.
11457 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11458 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11461 if (isSingleton(cpi.processName, cpi.applicationInfo,
11462 cpi.name, cpi.flags)
11463 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11464 userId = UserHandle.USER_SYSTEM;
11465 checkCrossUser = false;
11473 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11474 if (providerRunning) {
11477 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11478 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11480 throw new SecurityException(msg);
11482 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11484 if (r != null && cpr.canRunHere(r)) {
11485 // This provider has been published or is in the process
11486 // of being published... but it is also allowed to run
11487 // in the caller's process, so don't make a connection
11488 // and just let the caller instantiate its own instance.
11489 ContentProviderHolder holder = cpr.newHolder(null);
11490 // don't give caller the provider object, it needs
11491 // to make its own.
11492 holder.provider = null;
11495 // Don't expose providers between normal apps and instant apps
11497 if (AppGlobals.getPackageManager()
11498 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11501 } catch (RemoteException e) {
11504 final long origId = Binder.clearCallingIdentity();
11506 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11508 // In this case the provider instance already exists, so we can
11509 // return it right away.
11510 conn = incProviderCountLocked(r, cpr, token, stable);
11511 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11512 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11513 // If this is a perceptible app accessing the provider,
11514 // make sure to count it as being accessed and thus
11515 // back up on the LRU list. This is good because
11516 // content providers are often expensive to start.
11517 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11518 updateLruProcessLocked(cpr.proc, false, null);
11519 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11523 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11524 final int verifiedAdj = cpr.proc.verifiedAdj;
11525 boolean success = updateOomAdjLocked(cpr.proc, true);
11526 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11527 // if the process has been successfully adjusted. So to reduce races with
11528 // it, we will check whether the process still exists. Note that this doesn't
11529 // completely get rid of races with LMK killing the process, but should make
11530 // them much smaller.
11531 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11534 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11535 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11536 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11537 // NOTE: there is still a race here where a signal could be
11538 // pending on the process even though we managed to update its
11539 // adj level. Not sure what to do about this, but at least
11540 // the race is now smaller.
11542 // Uh oh... it looks like the provider's process
11543 // has been killed on us. We need to wait for a new
11544 // process to be started, and make sure its death
11545 // doesn't kill our process.
11546 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11547 + " is crashing; detaching " + r);
11548 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11549 checkTime(startTime, "getContentProviderImpl: before appDied");
11550 appDiedLocked(cpr.proc);
11551 checkTime(startTime, "getContentProviderImpl: after appDied");
11553 // This wasn't the last ref our process had on
11554 // the provider... we have now been killed, bail.
11557 providerRunning = false;
11560 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11563 Binder.restoreCallingIdentity(origId);
11566 if (!providerRunning) {
11568 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11569 cpi = AppGlobals.getPackageManager().
11570 resolveContentProvider(name,
11571 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11572 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11573 } catch (RemoteException ex) {
11578 // If the provider is a singleton AND
11579 // (it's a call within the same user || the provider is a
11581 // Then allow connecting to the singleton provider
11582 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11583 cpi.name, cpi.flags)
11584 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11586 userId = UserHandle.USER_SYSTEM;
11588 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11589 checkTime(startTime, "getContentProviderImpl: got app info for user");
11592 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11593 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11595 throw new SecurityException(msg);
11597 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11599 if (!mProcessesReady
11600 && !cpi.processName.equals("system")) {
11601 // If this content provider does not run in the system
11602 // process, and the system is not yet ready to run other
11603 // processes, then fail fast instead of hanging.
11604 throw new IllegalArgumentException(
11605 "Attempt to launch content provider before system ready");
11608 // Make sure that the user who owns this provider is running. If not,
11609 // we don't want to allow it to run.
11610 if (!mUserController.isUserRunningLocked(userId, 0)) {
11611 Slog.w(TAG, "Unable to launch app "
11612 + cpi.applicationInfo.packageName + "/"
11613 + cpi.applicationInfo.uid + " for provider "
11614 + name + ": user " + userId + " is stopped");
11618 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11619 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11620 cpr = mProviderMap.getProviderByClass(comp, userId);
11621 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11622 final boolean firstClass = cpr == null;
11624 final long ident = Binder.clearCallingIdentity();
11626 // If permissions need a review before any of the app components can run,
11627 // we return no provider and launch a review activity if the calling app
11628 // is in the foreground.
11629 if (mPermissionReviewRequired) {
11630 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11636 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11637 ApplicationInfo ai =
11638 AppGlobals.getPackageManager().
11639 getApplicationInfo(
11640 cpi.applicationInfo.packageName,
11641 STOCK_PM_FLAGS, userId);
11642 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11644 Slog.w(TAG, "No package info for content provider "
11648 ai = getAppInfoForUser(ai, userId);
11649 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11650 } catch (RemoteException ex) {
11651 // pm is in same process, this will never happen.
11653 Binder.restoreCallingIdentity(ident);
11657 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11659 if (r != null && cpr.canRunHere(r)) {
11660 // If this is a multiprocess provider, then just return its
11661 // info and allow the caller to instantiate it. Only do
11662 // this if the provider is the same user as the caller's
11663 // process, or can run as root (so can be in any process).
11664 return cpr.newHolder(null);
11667 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11668 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11669 + cpr.info.name + " callers=" + Debug.getCallers(6));
11671 // This is single process, and our app is now connecting to it.
11672 // See if we are already in the process of launching this
11674 final int N = mLaunchingProviders.size();
11676 for (i = 0; i < N; i++) {
11677 if (mLaunchingProviders.get(i) == cpr) {
11682 // If the provider is not already being launched, then get it
11685 final long origId = Binder.clearCallingIdentity();
11688 // Content provider is now in use, its package can't be stopped.
11690 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11691 AppGlobals.getPackageManager().setPackageStoppedState(
11692 cpr.appInfo.packageName, false, userId);
11693 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11694 } catch (RemoteException e) {
11695 } catch (IllegalArgumentException e) {
11696 Slog.w(TAG, "Failed trying to unstop package "
11697 + cpr.appInfo.packageName + ": " + e);
11700 // Use existing process if already started
11701 checkTime(startTime, "getContentProviderImpl: looking for process record");
11702 ProcessRecord proc = getProcessRecordLocked(
11703 cpi.processName, cpr.appInfo.uid, false);
11704 if (proc != null && proc.thread != null && !proc.killed) {
11705 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11706 "Installing in existing process " + proc);
11707 if (!proc.pubProviders.containsKey(cpi.name)) {
11708 checkTime(startTime, "getContentProviderImpl: scheduling install");
11709 proc.pubProviders.put(cpi.name, cpr);
11711 proc.thread.scheduleInstallProvider(cpi);
11712 } catch (RemoteException e) {
11716 checkTime(startTime, "getContentProviderImpl: before start process");
11717 proc = startProcessLocked(cpi.processName,
11718 cpr.appInfo, false, 0, "content provider",
11719 new ComponentName(cpi.applicationInfo.packageName,
11720 cpi.name), false, false, false);
11721 checkTime(startTime, "getContentProviderImpl: after start process");
11722 if (proc == null) {
11723 Slog.w(TAG, "Unable to launch app "
11724 + cpi.applicationInfo.packageName + "/"
11725 + cpi.applicationInfo.uid + " for provider "
11726 + name + ": process is bad");
11730 cpr.launchingApp = proc;
11731 mLaunchingProviders.add(cpr);
11733 Binder.restoreCallingIdentity(origId);
11737 checkTime(startTime, "getContentProviderImpl: updating data structures");
11739 // Make sure the provider is published (the same provider class
11740 // may be published under multiple names).
11742 mProviderMap.putProviderByClass(comp, cpr);
11745 mProviderMap.putProviderByName(name, cpr);
11746 conn = incProviderCountLocked(r, cpr, token, stable);
11747 if (conn != null) {
11748 conn.waiting = true;
11751 checkTime(startTime, "getContentProviderImpl: done!");
11753 grantEphemeralAccessLocked(userId, null /*intent*/,
11754 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11757 // Wait for the provider to be published...
11758 synchronized (cpr) {
11759 while (cpr.provider == null) {
11760 if (cpr.launchingApp == null) {
11761 Slog.w(TAG, "Unable to launch app "
11762 + cpi.applicationInfo.packageName + "/"
11763 + cpi.applicationInfo.uid + " for provider "
11764 + name + ": launching app became null");
11765 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11766 UserHandle.getUserId(cpi.applicationInfo.uid),
11767 cpi.applicationInfo.packageName,
11768 cpi.applicationInfo.uid, name);
11772 if (DEBUG_MU) Slog.v(TAG_MU,
11773 "Waiting to start provider " + cpr
11774 + " launchingApp=" + cpr.launchingApp);
11775 if (conn != null) {
11776 conn.waiting = true;
11779 } catch (InterruptedException ex) {
11781 if (conn != null) {
11782 conn.waiting = false;
11787 return cpr != null ? cpr.newHolder(conn) : null;
11790 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11791 ProcessRecord r, final int userId) {
11792 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11793 cpi.packageName, userId)) {
11795 final boolean callerForeground = r == null || r.setSchedGroup
11796 != ProcessList.SCHED_GROUP_BACKGROUND;
11798 // Show a permission review UI only for starting from a foreground app
11799 if (!callerForeground) {
11800 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11801 + cpi.packageName + " requires a permissions review");
11805 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11806 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11807 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11808 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11810 if (DEBUG_PERMISSIONS_REVIEW) {
11811 Slog.i(TAG, "u" + userId + " Launching permission review "
11812 + "for package " + cpi.packageName);
11815 final UserHandle userHandle = new UserHandle(userId);
11816 mHandler.post(new Runnable() {
11818 public void run() {
11819 mContext.startActivityAsUser(intent, userHandle);
11829 PackageManagerInternal getPackageManagerInternalLocked() {
11830 if (mPackageManagerInt == null) {
11831 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11833 return mPackageManagerInt;
11837 public final ContentProviderHolder getContentProvider(
11838 IApplicationThread caller, String name, int userId, boolean stable) {
11839 enforceNotIsolatedCaller("getContentProvider");
11840 if (caller == null) {
11841 String msg = "null IApplicationThread when getting content provider "
11844 throw new SecurityException(msg);
11846 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11847 // with cross-user grant.
11848 return getContentProviderImpl(caller, name, null, stable, userId);
11851 public ContentProviderHolder getContentProviderExternal(
11852 String name, int userId, IBinder token) {
11853 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11854 "Do not have permission in call getContentProviderExternal()");
11855 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11856 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11857 return getContentProviderExternalUnchecked(name, token, userId);
11860 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11861 IBinder token, int userId) {
11862 return getContentProviderImpl(null, name, token, true, userId);
11866 * Drop a content provider from a ProcessRecord's bookkeeping
11868 public void removeContentProvider(IBinder connection, boolean stable) {
11869 enforceNotIsolatedCaller("removeContentProvider");
11870 long ident = Binder.clearCallingIdentity();
11872 synchronized (this) {
11873 ContentProviderConnection conn;
11875 conn = (ContentProviderConnection)connection;
11876 } catch (ClassCastException e) {
11877 String msg ="removeContentProvider: " + connection
11878 + " not a ContentProviderConnection";
11880 throw new IllegalArgumentException(msg);
11882 if (conn == null) {
11883 throw new NullPointerException("connection is null");
11885 if (decProviderCountLocked(conn, null, null, stable)) {
11886 updateOomAdjLocked();
11890 Binder.restoreCallingIdentity(ident);
11894 public void removeContentProviderExternal(String name, IBinder token) {
11895 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11896 "Do not have permission in call removeContentProviderExternal()");
11897 int userId = UserHandle.getCallingUserId();
11898 long ident = Binder.clearCallingIdentity();
11900 removeContentProviderExternalUnchecked(name, token, userId);
11902 Binder.restoreCallingIdentity(ident);
11906 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11907 synchronized (this) {
11908 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11910 //remove from mProvidersByClass
11911 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11915 //update content provider record entry info
11916 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11917 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11918 if (localCpr.hasExternalProcessHandles()) {
11919 if (localCpr.removeExternalProcessHandleLocked(token)) {
11920 updateOomAdjLocked();
11922 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11923 + " with no external reference for token: "
11927 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11928 + " with no external references.");
11933 public final void publishContentProviders(IApplicationThread caller,
11934 List<ContentProviderHolder> providers) {
11935 if (providers == null) {
11939 enforceNotIsolatedCaller("publishContentProviders");
11940 synchronized (this) {
11941 final ProcessRecord r = getRecordForAppLocked(caller);
11942 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11944 throw new SecurityException(
11945 "Unable to find app for caller " + caller
11946 + " (pid=" + Binder.getCallingPid()
11947 + ") when publishing content providers");
11950 final long origId = Binder.clearCallingIdentity();
11952 final int N = providers.size();
11953 for (int i = 0; i < N; i++) {
11954 ContentProviderHolder src = providers.get(i);
11955 if (src == null || src.info == null || src.provider == null) {
11958 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11959 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11961 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11962 mProviderMap.putProviderByClass(comp, dst);
11963 String names[] = dst.info.authority.split(";");
11964 for (int j = 0; j < names.length; j++) {
11965 mProviderMap.putProviderByName(names[j], dst);
11968 int launchingCount = mLaunchingProviders.size();
11970 boolean wasInLaunchingProviders = false;
11971 for (j = 0; j < launchingCount; j++) {
11972 if (mLaunchingProviders.get(j) == dst) {
11973 mLaunchingProviders.remove(j);
11974 wasInLaunchingProviders = true;
11979 if (wasInLaunchingProviders) {
11980 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11982 synchronized (dst) {
11983 dst.provider = src.provider;
11987 updateOomAdjLocked(r, true);
11988 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11989 src.info.authority);
11993 Binder.restoreCallingIdentity(origId);
11997 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11998 ContentProviderConnection conn;
12000 conn = (ContentProviderConnection)connection;
12001 } catch (ClassCastException e) {
12002 String msg ="refContentProvider: " + connection
12003 + " not a ContentProviderConnection";
12005 throw new IllegalArgumentException(msg);
12007 if (conn == null) {
12008 throw new NullPointerException("connection is null");
12011 synchronized (this) {
12013 conn.numStableIncs += stable;
12015 stable = conn.stableCount + stable;
12017 throw new IllegalStateException("stableCount < 0: " + stable);
12020 if (unstable > 0) {
12021 conn.numUnstableIncs += unstable;
12023 unstable = conn.unstableCount + unstable;
12024 if (unstable < 0) {
12025 throw new IllegalStateException("unstableCount < 0: " + unstable);
12028 if ((stable+unstable) <= 0) {
12029 throw new IllegalStateException("ref counts can't go to zero here: stable="
12030 + stable + " unstable=" + unstable);
12032 conn.stableCount = stable;
12033 conn.unstableCount = unstable;
12038 public void unstableProviderDied(IBinder connection) {
12039 ContentProviderConnection conn;
12041 conn = (ContentProviderConnection)connection;
12042 } catch (ClassCastException e) {
12043 String msg ="refContentProvider: " + connection
12044 + " not a ContentProviderConnection";
12046 throw new IllegalArgumentException(msg);
12048 if (conn == null) {
12049 throw new NullPointerException("connection is null");
12052 // Safely retrieve the content provider associated with the connection.
12053 IContentProvider provider;
12054 synchronized (this) {
12055 provider = conn.provider.provider;
12058 if (provider == null) {
12059 // Um, yeah, we're way ahead of you.
12063 // Make sure the caller is being honest with us.
12064 if (provider.asBinder().pingBinder()) {
12065 // Er, no, still looks good to us.
12066 synchronized (this) {
12067 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12068 + " says " + conn + " died, but we don't agree");
12073 // Well look at that! It's dead!
12074 synchronized (this) {
12075 if (conn.provider.provider != provider) {
12076 // But something changed... good enough.
12080 ProcessRecord proc = conn.provider.proc;
12081 if (proc == null || proc.thread == null) {
12082 // Seems like the process is already cleaned up.
12086 // As far as we're concerned, this is just like receiving a
12087 // death notification... just a bit prematurely.
12088 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12089 + ") early provider death");
12090 final long ident = Binder.clearCallingIdentity();
12092 appDiedLocked(proc);
12094 Binder.restoreCallingIdentity(ident);
12100 public void appNotRespondingViaProvider(IBinder connection) {
12101 enforceCallingPermission(
12102 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12104 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12105 if (conn == null) {
12106 Slog.w(TAG, "ContentProviderConnection is null");
12110 final ProcessRecord host = conn.provider.proc;
12111 if (host == null) {
12112 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12116 mHandler.post(new Runnable() {
12118 public void run() {
12119 mAppErrors.appNotResponding(host, null, null, false,
12120 "ContentProvider not responding");
12125 public final void installSystemProviders() {
12126 List<ProviderInfo> providers;
12127 synchronized (this) {
12128 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12129 providers = generateApplicationProvidersLocked(app);
12130 if (providers != null) {
12131 for (int i=providers.size()-1; i>=0; i--) {
12132 ProviderInfo pi = (ProviderInfo)providers.get(i);
12133 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12134 Slog.w(TAG, "Not installing system proc provider " + pi.name
12135 + ": not system .apk");
12136 providers.remove(i);
12141 if (providers != null) {
12142 mSystemThread.installSystemProviders(providers);
12145 mConstants.start(mContext.getContentResolver());
12146 mCoreSettingsObserver = new CoreSettingsObserver(this);
12147 mFontScaleSettingObserver = new FontScaleSettingObserver();
12149 // Now that the settings provider is published we can consider sending
12150 // in a rescue party.
12151 RescueParty.onSettingsProviderPublished(mContext);
12153 //mUsageStatsService.monitorPackages();
12156 private void startPersistentApps(int matchFlags) {
12157 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12159 synchronized (this) {
12161 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12162 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12163 for (ApplicationInfo app : apps) {
12164 if (!"android".equals(app.packageName)) {
12165 addAppLocked(app, null, false, null /* ABI override */);
12168 } catch (RemoteException ex) {
12174 * When a user is unlocked, we need to install encryption-unaware providers
12175 * belonging to any running apps.
12177 private void installEncryptionUnawareProviders(int userId) {
12178 // We're only interested in providers that are encryption unaware, and
12179 // we don't care about uninstalled apps, since there's no way they're
12180 // running at this point.
12181 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12183 synchronized (this) {
12184 final int NP = mProcessNames.getMap().size();
12185 for (int ip = 0; ip < NP; ip++) {
12186 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12187 final int NA = apps.size();
12188 for (int ia = 0; ia < NA; ia++) {
12189 final ProcessRecord app = apps.valueAt(ia);
12190 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12192 final int NG = app.pkgList.size();
12193 for (int ig = 0; ig < NG; ig++) {
12195 final String pkgName = app.pkgList.keyAt(ig);
12196 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12197 .getPackageInfo(pkgName, matchFlags, userId);
12198 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12199 for (ProviderInfo pi : pkgInfo.providers) {
12200 // TODO: keep in sync with generateApplicationProvidersLocked
12201 final boolean processMatch = Objects.equals(pi.processName,
12202 app.processName) || pi.multiprocess;
12203 final boolean userMatch = isSingleton(pi.processName,
12204 pi.applicationInfo, pi.name, pi.flags)
12205 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12206 if (processMatch && userMatch) {
12207 Log.v(TAG, "Installing " + pi);
12208 app.thread.scheduleInstallProvider(pi);
12210 Log.v(TAG, "Skipping " + pi);
12214 } catch (RemoteException ignored) {
12223 * Allows apps to retrieve the MIME type of a URI.
12224 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12225 * users, then it does not need permission to access the ContentProvider.
12226 * Either, it needs cross-user uri grants.
12228 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12230 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12231 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12233 public String getProviderMimeType(Uri uri, int userId) {
12234 enforceNotIsolatedCaller("getProviderMimeType");
12235 final String name = uri.getAuthority();
12236 int callingUid = Binder.getCallingUid();
12237 int callingPid = Binder.getCallingPid();
12239 boolean clearedIdentity = false;
12240 synchronized (this) {
12241 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12243 if (canClearIdentity(callingPid, callingUid, userId)) {
12244 clearedIdentity = true;
12245 ident = Binder.clearCallingIdentity();
12247 ContentProviderHolder holder = null;
12249 holder = getContentProviderExternalUnchecked(name, null, userId);
12250 if (holder != null) {
12251 return holder.provider.getType(uri);
12253 } catch (RemoteException e) {
12254 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12256 } catch (Exception e) {
12257 Log.w(TAG, "Exception while determining type of " + uri, e);
12260 // We need to clear the identity to call removeContentProviderExternalUnchecked
12261 if (!clearedIdentity) {
12262 ident = Binder.clearCallingIdentity();
12265 if (holder != null) {
12266 removeContentProviderExternalUnchecked(name, null, userId);
12269 Binder.restoreCallingIdentity(ident);
12276 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12277 if (UserHandle.getUserId(callingUid) == userId) {
12280 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12281 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12282 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12283 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12289 // =========================================================
12290 // GLOBAL MANAGEMENT
12291 // =========================================================
12293 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12294 boolean isolated, int isolatedUid) {
12295 String proc = customProcess != null ? customProcess : info.processName;
12296 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12297 final int userId = UserHandle.getUserId(info.uid);
12298 int uid = info.uid;
12300 if (isolatedUid == 0) {
12301 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12303 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12304 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12305 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12307 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12308 mNextIsolatedProcessUid++;
12309 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12310 // No process for this uid, use it.
12314 if (stepsLeft <= 0) {
12319 // Special case for startIsolatedProcess (internal only), where
12320 // the uid of the isolated process is specified by the caller.
12323 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12325 // Register the isolated UID with this application so BatteryStats knows to
12326 // attribute resource usage to the application.
12328 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12329 // about the process state of the isolated UID *before* it is registered with the
12330 // owning application.
12331 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12333 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12334 if (!mBooted && !mBooting
12335 && userId == UserHandle.USER_SYSTEM
12336 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12337 r.persistent = true;
12338 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12340 addProcessNameLocked(r);
12344 private boolean uidOnBackgroundWhitelist(final int uid) {
12345 final int appId = UserHandle.getAppId(uid);
12346 final int[] whitelist = mBackgroundAppIdWhitelist;
12347 final int N = whitelist.length;
12348 for (int i = 0; i < N; i++) {
12349 if (appId == whitelist[i]) {
12357 public void backgroundWhitelistUid(final int uid) {
12358 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12359 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12362 if (DEBUG_BACKGROUND_CHECK) {
12363 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12365 synchronized (this) {
12366 final int N = mBackgroundAppIdWhitelist.length;
12367 int[] newList = new int[N+1];
12368 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12369 newList[N] = UserHandle.getAppId(uid);
12370 mBackgroundAppIdWhitelist = newList;
12374 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12375 String abiOverride) {
12378 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12385 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12386 updateLruProcessLocked(app, false, null);
12387 updateOomAdjLocked();
12390 // This package really, really can not be stopped.
12392 AppGlobals.getPackageManager().setPackageStoppedState(
12393 info.packageName, false, UserHandle.getUserId(app.uid));
12394 } catch (RemoteException e) {
12395 } catch (IllegalArgumentException e) {
12396 Slog.w(TAG, "Failed trying to unstop package "
12397 + info.packageName + ": " + e);
12400 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12401 app.persistent = true;
12402 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12404 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12405 mPersistentStartingProcesses.add(app);
12406 startProcessLocked(app, "added application",
12407 customProcess != null ? customProcess : app.processName, abiOverride,
12408 null /* entryPoint */, null /* entryPointArgs */);
12414 public void unhandledBack() {
12415 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12416 "unhandledBack()");
12418 synchronized(this) {
12419 final long origId = Binder.clearCallingIdentity();
12421 getFocusedStack().unhandledBackLocked();
12423 Binder.restoreCallingIdentity(origId);
12428 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12429 enforceNotIsolatedCaller("openContentUri");
12430 final int userId = UserHandle.getCallingUserId();
12431 final Uri uri = Uri.parse(uriString);
12432 String name = uri.getAuthority();
12433 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12434 ParcelFileDescriptor pfd = null;
12436 // We record the binder invoker's uid in thread-local storage before
12437 // going to the content provider to open the file. Later, in the code
12438 // that handles all permissions checks, we look for this uid and use
12439 // that rather than the Activity Manager's own uid. The effect is that
12440 // we do the check against the caller's permissions even though it looks
12441 // to the content provider like the Activity Manager itself is making
12443 Binder token = new Binder();
12444 sCallerIdentity.set(new Identity(
12445 token, Binder.getCallingPid(), Binder.getCallingUid()));
12447 pfd = cph.provider.openFile(null, uri, "r", null, token);
12448 } catch (FileNotFoundException e) {
12449 // do nothing; pfd will be returned null
12451 // Ensure that whatever happens, we clean up the identity state
12452 sCallerIdentity.remove();
12453 // Ensure we're done with the provider.
12454 removeContentProviderExternalUnchecked(name, null, userId);
12457 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12462 // Actually is sleeping or shutting down or whatever else in the future
12463 // is an inactive state.
12464 boolean isSleepingOrShuttingDownLocked() {
12465 return isSleepingLocked() || mShuttingDown;
12468 boolean isShuttingDownLocked() {
12469 return mShuttingDown;
12472 boolean isSleepingLocked() {
12476 void onWakefulnessChanged(int wakefulness) {
12477 synchronized(this) {
12478 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12479 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12480 mWakefulness = wakefulness;
12482 if (wasAwake != isAwake) {
12483 // Also update state in a special way for running foreground services UI.
12484 mServices.updateScreenStateLocked(isAwake);
12485 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12491 void finishRunningVoiceLocked() {
12492 if (mRunningVoice != null) {
12493 mRunningVoice = null;
12494 mVoiceWakeLock.release();
12495 updateSleepIfNeededLocked();
12499 void startTimeTrackingFocusedActivityLocked() {
12500 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12501 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12502 mCurAppTimeTracker.start(resumedActivity.packageName);
12506 void updateSleepIfNeededLocked() {
12507 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12508 final boolean wasSleeping = mSleeping;
12510 if (!shouldSleep) {
12511 // If wasSleeping is true, we need to wake up activity manager state from when
12512 // we started sleeping. In either case, we need to apply the sleep tokens, which
12513 // will wake up stacks or put them to sleep as appropriate.
12516 startTimeTrackingFocusedActivityLocked();
12517 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12518 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12520 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12522 updateOomAdjLocked();
12524 } else if (!mSleeping && shouldSleep) {
12526 if (mCurAppTimeTracker != null) {
12527 mCurAppTimeTracker.stop();
12529 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12530 mStackSupervisor.goingToSleepLocked();
12531 updateOomAdjLocked();
12535 /** Pokes the task persister. */
12536 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12537 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12541 * Notifies all listeners when the pinned stack animation starts.
12544 public void notifyPinnedStackAnimationStarted() {
12545 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12549 * Notifies all listeners when the pinned stack animation ends.
12552 public void notifyPinnedStackAnimationEnded() {
12553 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12557 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12558 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12562 public boolean shutdown(int timeout) {
12563 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12564 != PackageManager.PERMISSION_GRANTED) {
12565 throw new SecurityException("Requires permission "
12566 + android.Manifest.permission.SHUTDOWN);
12569 boolean timedout = false;
12571 synchronized(this) {
12572 mShuttingDown = true;
12573 mStackSupervisor.prepareForShutdownLocked();
12574 updateEventDispatchingLocked();
12575 timedout = mStackSupervisor.shutdownLocked(timeout);
12578 mAppOpsService.shutdown();
12579 if (mUsageStatsService != null) {
12580 mUsageStatsService.prepareShutdown();
12582 mBatteryStatsService.shutdown();
12583 synchronized (this) {
12584 mProcessStats.shutdownLocked();
12585 notifyTaskPersisterLocked(null, true);
12591 public final void activitySlept(IBinder token) {
12592 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12594 final long origId = Binder.clearCallingIdentity();
12596 synchronized (this) {
12597 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12599 mStackSupervisor.activitySleptLocked(r);
12603 Binder.restoreCallingIdentity(origId);
12606 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12607 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12608 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12609 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12610 boolean wasRunningVoice = mRunningVoice != null;
12611 mRunningVoice = session;
12612 if (!wasRunningVoice) {
12613 mVoiceWakeLock.acquire();
12614 updateSleepIfNeededLocked();
12619 private void updateEventDispatchingLocked() {
12620 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12624 public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12625 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12626 != PackageManager.PERMISSION_GRANTED) {
12627 throw new SecurityException("Requires permission "
12628 + android.Manifest.permission.DEVICE_POWER);
12631 synchronized(this) {
12632 long ident = Binder.clearCallingIdentity();
12634 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12636 Binder.restoreCallingIdentity(ident);
12640 mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12645 public void notifyLockedProfile(@UserIdInt int userId) {
12647 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12648 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12650 } catch (RemoteException ex) {
12651 throw new SecurityException("Fail to check is caller a privileged app", ex);
12654 synchronized (this) {
12655 final long ident = Binder.clearCallingIdentity();
12657 if (mUserController.shouldConfirmCredentials(userId)) {
12658 if (mKeyguardController.isKeyguardLocked()) {
12659 // Showing launcher to avoid user entering credential twice.
12660 final int currentUserId = mUserController.getCurrentUserIdLocked();
12661 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12663 mStackSupervisor.lockAllProfileTasks(userId);
12666 Binder.restoreCallingIdentity(ident);
12672 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12673 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12674 synchronized (this) {
12675 final long ident = Binder.clearCallingIdentity();
12677 mActivityStarter.startConfirmCredentialIntent(intent, options);
12679 Binder.restoreCallingIdentity(ident);
12685 public void stopAppSwitches() {
12686 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12687 != PackageManager.PERMISSION_GRANTED) {
12688 throw new SecurityException("viewquires permission "
12689 + android.Manifest.permission.STOP_APP_SWITCHES);
12692 synchronized(this) {
12693 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12694 + APP_SWITCH_DELAY_TIME;
12695 mDidAppSwitch = false;
12696 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12697 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12698 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12702 public void resumeAppSwitches() {
12703 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12704 != PackageManager.PERMISSION_GRANTED) {
12705 throw new SecurityException("Requires permission "
12706 + android.Manifest.permission.STOP_APP_SWITCHES);
12709 synchronized(this) {
12710 // Note that we don't execute any pending app switches... we will
12711 // let those wait until either the timeout, or the next start
12712 // activity request.
12713 mAppSwitchesAllowedTime = 0;
12717 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12718 int callingPid, int callingUid, String name) {
12719 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12723 int perm = checkComponentPermission(
12724 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12725 sourceUid, -1, true);
12726 if (perm == PackageManager.PERMISSION_GRANTED) {
12730 // If the actual IPC caller is different from the logical source, then
12731 // also see if they are allowed to control app switches.
12732 if (callingUid != -1 && callingUid != sourceUid) {
12733 perm = checkComponentPermission(
12734 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12735 callingUid, -1, true);
12736 if (perm == PackageManager.PERMISSION_GRANTED) {
12741 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12745 public void setDebugApp(String packageName, boolean waitForDebugger,
12746 boolean persistent) {
12747 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12750 long ident = Binder.clearCallingIdentity();
12752 // Note that this is not really thread safe if there are multiple
12753 // callers into it at the same time, but that's not a situation we
12756 final ContentResolver resolver = mContext.getContentResolver();
12757 Settings.Global.putString(
12758 resolver, Settings.Global.DEBUG_APP,
12760 Settings.Global.putInt(
12761 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12762 waitForDebugger ? 1 : 0);
12765 synchronized (this) {
12767 mOrigDebugApp = mDebugApp;
12768 mOrigWaitForDebugger = mWaitForDebugger;
12770 mDebugApp = packageName;
12771 mWaitForDebugger = waitForDebugger;
12772 mDebugTransient = !persistent;
12773 if (packageName != null) {
12774 forceStopPackageLocked(packageName, -1, false, false, true, true,
12775 false, UserHandle.USER_ALL, "set debug app");
12779 Binder.restoreCallingIdentity(ident);
12783 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12784 synchronized (this) {
12785 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12786 if (!isDebuggable) {
12787 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12788 throw new SecurityException("Process not debuggable: " + app.packageName);
12792 mTrackAllocationApp = processName;
12796 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12797 synchronized (this) {
12798 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12799 if (!isDebuggable) {
12800 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12801 throw new SecurityException("Process not debuggable: " + app.packageName);
12804 mProfileApp = processName;
12806 if (mProfilerInfo != null) {
12807 if (mProfilerInfo.profileFd != null) {
12809 mProfilerInfo.profileFd.close();
12810 } catch (IOException e) {
12814 mProfilerInfo = new ProfilerInfo(profilerInfo);
12819 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12820 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12821 if (!isDebuggable) {
12822 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12823 throw new SecurityException("Process not debuggable: " + app.packageName);
12826 mNativeDebuggingApp = processName;
12830 public void setAlwaysFinish(boolean enabled) {
12831 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12832 "setAlwaysFinish()");
12834 long ident = Binder.clearCallingIdentity();
12836 Settings.Global.putInt(
12837 mContext.getContentResolver(),
12838 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12840 synchronized (this) {
12841 mAlwaysFinishActivities = enabled;
12844 Binder.restoreCallingIdentity(ident);
12849 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12850 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12851 "setActivityController()");
12852 synchronized (this) {
12853 mController = controller;
12854 mControllerIsAMonkey = imAMonkey;
12855 Watchdog.getInstance().setActivityController(controller);
12860 public void setUserIsMonkey(boolean userIsMonkey) {
12861 synchronized (this) {
12862 synchronized (mPidsSelfLocked) {
12863 final int callingPid = Binder.getCallingPid();
12864 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12865 if (proc == null) {
12866 throw new SecurityException("Unknown process: " + callingPid);
12868 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12869 throw new SecurityException("Only an instrumentation process "
12870 + "with a UiAutomation can call setUserIsMonkey");
12873 mUserIsMonkey = userIsMonkey;
12878 public boolean isUserAMonkey() {
12879 synchronized (this) {
12880 // If there is a controller also implies the user is a monkey.
12881 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12886 * @deprecated This method is only used by a few internal components and it will soon be
12887 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12888 * No new code should be calling it.
12892 public void requestBugReport(int bugreportType) {
12893 String extraOptions = null;
12894 switch (bugreportType) {
12895 case ActivityManager.BUGREPORT_OPTION_FULL:
12896 // Default options.
12898 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12899 extraOptions = "bugreportplus";
12901 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12902 extraOptions = "bugreportremote";
12904 case ActivityManager.BUGREPORT_OPTION_WEAR:
12905 extraOptions = "bugreportwear";
12907 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12908 extraOptions = "bugreporttelephony";
12911 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12914 // Always log caller, even if it does not have permission to dump.
12915 String type = extraOptions == null ? "bugreport" : extraOptions;
12916 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12918 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12919 if (extraOptions != null) {
12920 SystemProperties.set("dumpstate.options", extraOptions);
12922 SystemProperties.set("ctl.start", "bugreport");
12926 * @deprecated This method is only used by a few internal components and it will soon be
12927 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12928 * No new code should be calling it.
12932 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12934 if (!TextUtils.isEmpty(shareTitle)) {
12935 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12936 String errorStr = "shareTitle should be less than " +
12937 MAX_BUGREPORT_TITLE_SIZE + " characters";
12938 throw new IllegalArgumentException(errorStr);
12940 if (!TextUtils.isEmpty(shareDescription)) {
12943 length = shareDescription.getBytes("UTF-8").length;
12944 } catch (UnsupportedEncodingException e) {
12945 String errorStr = "shareDescription: UnsupportedEncodingException";
12946 throw new IllegalArgumentException(errorStr);
12948 if (length > SystemProperties.PROP_VALUE_MAX) {
12949 String errorStr = "shareTitle should be less than " +
12950 SystemProperties.PROP_VALUE_MAX + " bytes";
12951 throw new IllegalArgumentException(errorStr);
12953 SystemProperties.set("dumpstate.options.description", shareDescription);
12956 SystemProperties.set("dumpstate.options.title", shareTitle);
12960 Slog.d(TAG, "Bugreport notification title " + shareTitle
12961 + " description " + shareDescription);
12962 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12965 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12966 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12969 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12970 if (r != null && (r.instr != null || r.usingWrapper)) {
12971 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12973 return KEY_DISPATCHING_TIMEOUT;
12977 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12978 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12979 != PackageManager.PERMISSION_GRANTED) {
12980 throw new SecurityException("Requires permission "
12981 + android.Manifest.permission.FILTER_EVENTS);
12983 ProcessRecord proc;
12985 synchronized (this) {
12986 synchronized (mPidsSelfLocked) {
12987 proc = mPidsSelfLocked.get(pid);
12989 timeout = getInputDispatchingTimeoutLocked(proc);
12992 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13000 * Handle input dispatching timeouts.
13001 * Returns whether input dispatching should be aborted or not.
13003 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13004 final ActivityRecord activity, final ActivityRecord parent,
13005 final boolean aboveSystem, String reason) {
13006 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13007 != PackageManager.PERMISSION_GRANTED) {
13008 throw new SecurityException("Requires permission "
13009 + android.Manifest.permission.FILTER_EVENTS);
13012 final String annotation;
13013 if (reason == null) {
13014 annotation = "Input dispatching timed out";
13016 annotation = "Input dispatching timed out (" + reason + ")";
13019 if (proc != null) {
13020 synchronized (this) {
13021 if (proc.debugging) {
13025 if (proc.instr != null) {
13026 Bundle info = new Bundle();
13027 info.putString("shortMsg", "keyDispatchingTimedOut");
13028 info.putString("longMsg", annotation);
13029 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13033 mHandler.post(new Runnable() {
13035 public void run() {
13036 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13045 public Bundle getAssistContextExtras(int requestType) {
13046 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13047 null, null, true /* focused */, true /* newSessionId */,
13048 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13052 synchronized (pae) {
13053 while (!pae.haveResult) {
13056 } catch (InterruptedException e) {
13060 synchronized (this) {
13061 buildAssistBundleLocked(pae, pae.result);
13062 mPendingAssistExtras.remove(pae);
13063 mUiHandler.removeCallbacks(pae);
13069 public boolean isAssistDataAllowedOnCurrentActivity() {
13071 synchronized (this) {
13072 final ActivityStack focusedStack = getFocusedStack();
13073 if (focusedStack == null || focusedStack.isAssistantStack()) {
13077 final ActivityRecord activity = focusedStack.topActivity();
13078 if (activity == null) {
13081 userId = activity.userId;
13083 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13084 Context.DEVICE_POLICY_SERVICE);
13085 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13089 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13090 long ident = Binder.clearCallingIdentity();
13092 synchronized (this) {
13093 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13094 ActivityRecord top = getFocusedStack().topActivity();
13095 if (top != caller) {
13096 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13097 + " is not current top " + top);
13100 if (!top.nowVisible) {
13101 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13102 + " is not visible");
13106 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13109 Binder.restoreCallingIdentity(ident);
13114 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13115 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13116 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13117 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13118 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13122 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13123 IBinder activityToken, int flags) {
13124 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13125 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13126 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13129 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13130 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13131 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13133 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13134 "enqueueAssistContext()");
13136 synchronized (this) {
13137 ActivityRecord activity = getFocusedStack().topActivity();
13138 if (activity == null) {
13139 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13142 if (activity.app == null || activity.app.thread == null) {
13143 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13147 if (activityToken != null) {
13148 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13149 if (activity != caller) {
13150 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13151 + " is not current top " + activity);
13156 activity = ActivityRecord.forTokenLocked(activityToken);
13157 if (activity == null) {
13158 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13159 + " couldn't be found");
13162 if (activity.app == null || activity.app.thread == null) {
13163 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13168 PendingAssistExtras pae;
13169 Bundle extras = new Bundle();
13170 if (args != null) {
13171 extras.putAll(args);
13173 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13174 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13176 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13178 pae.isHome = activity.isHomeActivity();
13180 // Increment the sessionId if necessary
13181 if (newSessionId) {
13185 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13186 mViSessionId, flags);
13187 mPendingAssistExtras.add(pae);
13188 mUiHandler.postDelayed(pae, timeout);
13189 } catch (RemoteException e) {
13190 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13197 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13198 IResultReceiver receiver;
13199 synchronized (this) {
13200 mPendingAssistExtras.remove(pae);
13201 receiver = pae.receiver;
13203 if (receiver != null) {
13204 // Caller wants result sent back to them.
13205 Bundle sendBundle = new Bundle();
13206 // At least return the receiver extras
13207 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13208 pae.receiverExtras);
13210 pae.receiver.send(0, sendBundle);
13211 } catch (RemoteException e) {
13216 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13217 if (result != null) {
13218 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13220 if (pae.hint != null) {
13221 pae.extras.putBoolean(pae.hint, true);
13225 /** Called from an app when assist data is ready. */
13227 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13228 AssistContent content, Uri referrer) {
13229 PendingAssistExtras pae = (PendingAssistExtras)token;
13230 synchronized (pae) {
13231 pae.result = extras;
13232 pae.structure = structure;
13233 pae.content = content;
13234 if (referrer != null) {
13235 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13237 if (structure != null) {
13238 structure.setHomeActivity(pae.isHome);
13240 pae.haveResult = true;
13242 if (pae.intent == null && pae.receiver == null) {
13243 // Caller is just waiting for the result.
13247 // We are now ready to launch the assist activity.
13248 IResultReceiver sendReceiver = null;
13249 Bundle sendBundle = null;
13250 synchronized (this) {
13251 buildAssistBundleLocked(pae, extras);
13252 boolean exists = mPendingAssistExtras.remove(pae);
13253 mUiHandler.removeCallbacks(pae);
13258 if ((sendReceiver=pae.receiver) != null) {
13259 // Caller wants result sent back to them.
13260 sendBundle = new Bundle();
13261 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13262 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13263 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13264 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13265 pae.receiverExtras);
13268 if (sendReceiver != null) {
13270 sendReceiver.send(0, sendBundle);
13271 } catch (RemoteException e) {
13276 final long ident = Binder.clearCallingIdentity();
13278 if (TextUtils.equals(pae.intent.getAction(),
13279 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13280 pae.intent.putExtras(pae.extras);
13281 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13283 pae.intent.replaceExtras(pae.extras);
13284 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13285 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13286 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13287 closeSystemDialogs("assist");
13290 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13291 } catch (ActivityNotFoundException e) {
13292 Slog.w(TAG, "No activity to handle assist action.", e);
13296 Binder.restoreCallingIdentity(ident);
13300 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13302 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13303 true /* focused */, true /* newSessionId */, userHandle, args,
13304 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13307 public void registerProcessObserver(IProcessObserver observer) {
13308 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13309 "registerProcessObserver()");
13310 synchronized (this) {
13311 mProcessObservers.register(observer);
13316 public void unregisterProcessObserver(IProcessObserver observer) {
13317 synchronized (this) {
13318 mProcessObservers.unregister(observer);
13323 public int getUidProcessState(int uid, String callingPackage) {
13324 if (!hasUsageStatsPermission(callingPackage)) {
13325 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13326 "getUidProcessState");
13329 synchronized (this) {
13330 UidRecord uidRec = mActiveUids.get(uid);
13331 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13336 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13337 String callingPackage) {
13338 if (!hasUsageStatsPermission(callingPackage)) {
13339 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13340 "registerUidObserver");
13342 synchronized (this) {
13343 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13344 callingPackage, which, cutpoint));
13349 public void unregisterUidObserver(IUidObserver observer) {
13350 synchronized (this) {
13351 mUidObservers.unregister(observer);
13356 public boolean convertFromTranslucent(IBinder token) {
13357 final long origId = Binder.clearCallingIdentity();
13359 synchronized (this) {
13360 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13364 final boolean translucentChanged = r.changeWindowTranslucency(true);
13365 if (translucentChanged) {
13366 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13368 mWindowManager.setAppFullscreen(token, true);
13369 return translucentChanged;
13372 Binder.restoreCallingIdentity(origId);
13377 public boolean convertToTranslucent(IBinder token, Bundle options) {
13378 final long origId = Binder.clearCallingIdentity();
13380 synchronized (this) {
13381 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13385 final TaskRecord task = r.getTask();
13386 int index = task.mActivities.lastIndexOf(r);
13388 ActivityRecord under = task.mActivities.get(index - 1);
13389 under.returningOptions = ActivityOptions.fromBundle(options);
13391 final boolean translucentChanged = r.changeWindowTranslucency(false);
13392 if (translucentChanged) {
13393 r.getStack().convertActivityToTranslucent(r);
13395 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13396 mWindowManager.setAppFullscreen(token, false);
13397 return translucentChanged;
13400 Binder.restoreCallingIdentity(origId);
13405 public Bundle getActivityOptions(IBinder token) {
13406 final long origId = Binder.clearCallingIdentity();
13408 synchronized (this) {
13409 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13411 final ActivityOptions activityOptions = r.takeOptionsLocked();
13412 return activityOptions == null ? null : activityOptions.toBundle();
13417 Binder.restoreCallingIdentity(origId);
13422 public void setImmersive(IBinder token, boolean immersive) {
13423 synchronized(this) {
13424 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13426 throw new IllegalArgumentException();
13428 r.immersive = immersive;
13430 // update associated state if we're frontmost
13431 if (r == mStackSupervisor.getResumedActivityLocked()) {
13432 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13433 applyUpdateLockStateLocked(r);
13439 public boolean isImmersive(IBinder token) {
13440 synchronized (this) {
13441 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13443 throw new IllegalArgumentException();
13445 return r.immersive;
13450 public void setVrThread(int tid) {
13451 enforceSystemHasVrFeature();
13452 synchronized (this) {
13453 synchronized (mPidsSelfLocked) {
13454 final int pid = Binder.getCallingPid();
13455 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13456 mVrController.setVrThreadLocked(tid, pid, proc);
13462 public void setPersistentVrThread(int tid) {
13463 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13464 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13465 + Binder.getCallingPid()
13466 + ", uid=" + Binder.getCallingUid()
13467 + " requires " + permission.RESTRICTED_VR_ACCESS;
13469 throw new SecurityException(msg);
13471 enforceSystemHasVrFeature();
13472 synchronized (this) {
13473 synchronized (mPidsSelfLocked) {
13474 final int pid = Binder.getCallingPid();
13475 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13476 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13482 * Schedule the given thread a normal scheduling priority.
13484 * @param tid the tid of the thread to adjust the scheduling of.
13485 * @param suppressLogs {@code true} if any error logging should be disabled.
13487 * @return {@code true} if this succeeded.
13489 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13491 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13493 } catch (IllegalArgumentException e) {
13494 if (!suppressLogs) {
13495 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13497 } catch (SecurityException e) {
13498 if (!suppressLogs) {
13499 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13506 * Schedule the given thread an FIFO scheduling priority.
13508 * @param tid the tid of the thread to adjust the scheduling of.
13509 * @param suppressLogs {@code true} if any error logging should be disabled.
13511 * @return {@code true} if this succeeded.
13513 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13515 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13517 } catch (IllegalArgumentException e) {
13518 if (!suppressLogs) {
13519 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13521 } catch (SecurityException e) {
13522 if (!suppressLogs) {
13523 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13530 * Check that we have the features required for VR-related API calls, and throw an exception if
13533 private void enforceSystemHasVrFeature() {
13534 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13535 throw new UnsupportedOperationException("VR mode not supported on this device!");
13540 public void setRenderThread(int tid) {
13541 synchronized (this) {
13542 ProcessRecord proc;
13543 int pid = Binder.getCallingPid();
13544 if (pid == Process.myPid()) {
13545 demoteSystemServerRenderThread(tid);
13548 synchronized (mPidsSelfLocked) {
13549 proc = mPidsSelfLocked.get(pid);
13550 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13551 // ensure the tid belongs to the process
13552 if (!isThreadInProcess(pid, tid)) {
13553 throw new IllegalArgumentException(
13554 "Render thread does not belong to process");
13556 proc.renderThreadTid = tid;
13557 if (DEBUG_OOM_ADJ) {
13558 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13560 // promote to FIFO now
13561 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13562 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13563 if (mUseFifoUiScheduling) {
13564 setThreadScheduler(proc.renderThreadTid,
13565 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13567 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13571 if (DEBUG_OOM_ADJ) {
13572 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13573 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13574 mUseFifoUiScheduling);
13582 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13583 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13585 * @param tid the tid of the RenderThread
13587 private void demoteSystemServerRenderThread(int tid) {
13588 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13592 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13593 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13594 throw new UnsupportedOperationException("VR mode not supported on this device!");
13597 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13600 synchronized (this) {
13601 r = ActivityRecord.isInStackLocked(token);
13605 throw new IllegalArgumentException();
13609 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13610 VrManagerInternal.NO_ERROR) {
13614 synchronized(this) {
13615 r.requestedVrComponent = (enabled) ? packageName : null;
13617 // Update associated state if this activity is currently focused
13618 if (r == mStackSupervisor.getResumedActivityLocked()) {
13619 applyUpdateVrModeLocked(r);
13626 public boolean isVrModePackageEnabled(ComponentName packageName) {
13627 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13628 throw new UnsupportedOperationException("VR mode not supported on this device!");
13631 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13633 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13634 VrManagerInternal.NO_ERROR;
13637 public boolean isTopActivityImmersive() {
13638 enforceNotIsolatedCaller("startActivity");
13639 synchronized (this) {
13640 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13641 return (r != null) ? r.immersive : false;
13646 * @return whether the system should disable UI modes incompatible with VR mode.
13648 boolean shouldDisableNonVrUiLocked() {
13649 return mVrController.shouldDisableNonVrUiLocked();
13653 public boolean isTopOfTask(IBinder token) {
13654 synchronized (this) {
13655 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13657 throw new IllegalArgumentException();
13659 return r.getTask().getTopActivity() == r;
13664 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13665 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13666 String msg = "Permission Denial: setHasTopUi() from pid="
13667 + Binder.getCallingPid()
13668 + ", uid=" + Binder.getCallingUid()
13669 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13671 throw new SecurityException(msg);
13673 final int pid = Binder.getCallingPid();
13674 final long origId = Binder.clearCallingIdentity();
13676 synchronized (this) {
13677 boolean changed = false;
13679 synchronized (mPidsSelfLocked) {
13680 pr = mPidsSelfLocked.get(pid);
13682 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13685 if (pr.hasTopUi != hasTopUi) {
13686 if (DEBUG_OOM_ADJ) {
13687 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13689 pr.hasTopUi = hasTopUi;
13694 updateOomAdjLocked(pr, true);
13698 Binder.restoreCallingIdentity(origId);
13702 public final void enterSafeMode() {
13703 synchronized(this) {
13704 // It only makes sense to do this before the system is ready
13705 // and started launching other packages.
13706 if (!mSystemReady) {
13708 AppGlobals.getPackageManager().enterSafeMode();
13709 } catch (RemoteException e) {
13717 public final void showSafeModeOverlay() {
13718 View v = LayoutInflater.from(mContext).inflate(
13719 com.android.internal.R.layout.safe_mode, null);
13720 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13721 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13722 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13723 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13724 lp.gravity = Gravity.BOTTOM | Gravity.START;
13725 lp.format = v.getBackground().getOpacity();
13726 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13727 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13728 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13729 ((WindowManager)mContext.getSystemService(
13730 Context.WINDOW_SERVICE)).addView(v, lp);
13733 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13734 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13737 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13738 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13739 synchronized (stats) {
13740 if (mBatteryStatsService.isOnBattery()) {
13741 mBatteryStatsService.enforceCallingPermission();
13742 int MY_UID = Binder.getCallingUid();
13744 if (sender == null) {
13747 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13749 BatteryStatsImpl.Uid.Pkg pkg =
13750 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13751 sourcePkg != null ? sourcePkg : rec.key.packageName);
13752 pkg.noteWakeupAlarmLocked(tag);
13757 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13758 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13761 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13762 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13763 synchronized (stats) {
13764 mBatteryStatsService.enforceCallingPermission();
13765 int MY_UID = Binder.getCallingUid();
13767 if (sender == null) {
13770 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13772 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13776 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13777 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13780 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13781 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13782 synchronized (stats) {
13783 mBatteryStatsService.enforceCallingPermission();
13784 int MY_UID = Binder.getCallingUid();
13786 if (sender == null) {
13789 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13791 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13795 public boolean killPids(int[] pids, String pReason, boolean secure) {
13796 if (Binder.getCallingUid() != SYSTEM_UID) {
13797 throw new SecurityException("killPids only available to the system");
13799 String reason = (pReason == null) ? "Unknown" : pReason;
13800 // XXX Note: don't acquire main activity lock here, because the window
13801 // manager calls in with its locks held.
13803 boolean killed = false;
13804 synchronized (mPidsSelfLocked) {
13806 for (int i=0; i<pids.length; i++) {
13807 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13808 if (proc != null) {
13809 int type = proc.setAdj;
13810 if (type > worstType) {
13816 // If the worst oom_adj is somewhere in the cached proc LRU range,
13817 // then constrain it so we will kill all cached procs.
13818 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13819 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13820 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13823 // If this is not a secure call, don't let it kill processes that
13825 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13826 worstType = ProcessList.SERVICE_ADJ;
13829 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13830 for (int i=0; i<pids.length; i++) {
13831 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13832 if (proc == null) {
13835 int adj = proc.setAdj;
13836 if (adj >= worstType && !proc.killedByAm) {
13837 proc.kill(reason, true);
13846 public void killUid(int appId, int userId, String reason) {
13847 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13848 synchronized (this) {
13849 final long identity = Binder.clearCallingIdentity();
13851 killPackageProcessesLocked(null, appId, userId,
13852 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13853 reason != null ? reason : "kill uid");
13855 Binder.restoreCallingIdentity(identity);
13861 public boolean killProcessesBelowForeground(String reason) {
13862 if (Binder.getCallingUid() != SYSTEM_UID) {
13863 throw new SecurityException("killProcessesBelowForeground() only available to system");
13866 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13869 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13870 if (Binder.getCallingUid() != SYSTEM_UID) {
13871 throw new SecurityException("killProcessesBelowAdj() only available to system");
13874 boolean killed = false;
13875 synchronized (mPidsSelfLocked) {
13876 final int size = mPidsSelfLocked.size();
13877 for (int i = 0; i < size; i++) {
13878 final int pid = mPidsSelfLocked.keyAt(i);
13879 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13880 if (proc == null) continue;
13882 final int adj = proc.setAdj;
13883 if (adj > belowAdj && !proc.killedByAm) {
13884 proc.kill(reason, true);
13893 public void hang(final IBinder who, boolean allowRestart) {
13894 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13895 != PackageManager.PERMISSION_GRANTED) {
13896 throw new SecurityException("Requires permission "
13897 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13900 final IBinder.DeathRecipient death = new DeathRecipient() {
13902 public void binderDied() {
13903 synchronized (this) {
13910 who.linkToDeath(death, 0);
13911 } catch (RemoteException e) {
13912 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13916 synchronized (this) {
13917 Watchdog.getInstance().setAllowRestart(allowRestart);
13918 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13919 synchronized (death) {
13920 while (who.isBinderAlive()) {
13923 } catch (InterruptedException e) {
13927 Watchdog.getInstance().setAllowRestart(true);
13932 public void restart() {
13933 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13934 != PackageManager.PERMISSION_GRANTED) {
13935 throw new SecurityException("Requires permission "
13936 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13939 Log.i(TAG, "Sending shutdown broadcast...");
13941 BroadcastReceiver br = new BroadcastReceiver() {
13942 @Override public void onReceive(Context context, Intent intent) {
13943 // Now the broadcast is done, finish up the low-level shutdown.
13944 Log.i(TAG, "Shutting down activity manager...");
13946 Log.i(TAG, "Shutdown complete, restarting!");
13947 killProcess(myPid());
13952 // First send the high-level shut down broadcast.
13953 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13954 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13955 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13956 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13957 mContext.sendOrderedBroadcastAsUser(intent,
13958 UserHandle.ALL, null, br, mHandler, 0, null, null);
13960 br.onReceive(mContext, intent);
13963 private long getLowRamTimeSinceIdle(long now) {
13964 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13968 public void performIdleMaintenance() {
13969 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13970 != PackageManager.PERMISSION_GRANTED) {
13971 throw new SecurityException("Requires permission "
13972 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13975 synchronized (this) {
13976 final long now = SystemClock.uptimeMillis();
13977 final long timeSinceLastIdle = now - mLastIdleTime;
13978 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13979 mLastIdleTime = now;
13980 mLowRamTimeSinceLastIdle = 0;
13981 if (mLowRamStartTime != 0) {
13982 mLowRamStartTime = now;
13985 StringBuilder sb = new StringBuilder(128);
13986 sb.append("Idle maintenance over ");
13987 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13988 sb.append(" low RAM for ");
13989 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13990 Slog.i(TAG, sb.toString());
13992 // If at least 1/3 of our time since the last idle period has been spent
13993 // with RAM low, then we want to kill processes.
13994 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13996 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13997 ProcessRecord proc = mLruProcesses.get(i);
13998 if (proc.notCachedSinceIdle) {
13999 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14000 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14001 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14002 if (doKilling && proc.initialIdlePss != 0
14003 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14004 sb = new StringBuilder(128);
14006 sb.append(proc.processName);
14007 sb.append(" in idle maint: pss=");
14008 sb.append(proc.lastPss);
14009 sb.append(", swapPss=");
14010 sb.append(proc.lastSwapPss);
14011 sb.append(", initialPss=");
14012 sb.append(proc.initialIdlePss);
14013 sb.append(", period=");
14014 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14015 sb.append(", lowRamPeriod=");
14016 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14017 Slog.wtfQuiet(TAG, sb.toString());
14018 proc.kill("idle maint (pss " + proc.lastPss
14019 + " from " + proc.initialIdlePss + ")", true);
14022 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14023 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14024 proc.notCachedSinceIdle = true;
14025 proc.initialIdlePss = 0;
14026 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14027 mTestPssMode, isSleepingLocked(), now);
14031 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14032 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14037 public void sendIdleJobTrigger() {
14038 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14039 != PackageManager.PERMISSION_GRANTED) {
14040 throw new SecurityException("Requires permission "
14041 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14044 final long ident = Binder.clearCallingIdentity();
14046 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14047 .setPackage("android")
14048 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14049 broadcastIntent(null, intent, null, null, 0, null, null, null,
14050 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14052 Binder.restoreCallingIdentity(ident);
14056 private void retrieveSettings() {
14057 final ContentResolver resolver = mContext.getContentResolver();
14058 final boolean freeformWindowManagement =
14059 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14060 || Settings.Global.getInt(
14061 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14063 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14064 final boolean supportsPictureInPicture = supportsMultiWindow &&
14065 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14066 final boolean supportsSplitScreenMultiWindow =
14067 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14068 final boolean supportsMultiDisplay = mContext.getPackageManager()
14069 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14070 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14071 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14072 final boolean alwaysFinishActivities =
14073 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14074 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14075 final boolean forceResizable = Settings.Global.getInt(
14076 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14077 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14078 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14079 final boolean supportsLeanbackOnly =
14080 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14082 // Transfer any global setting for forcing RTL layout, into a System Property
14083 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14085 final Configuration configuration = new Configuration();
14086 Settings.System.getConfiguration(resolver, configuration);
14088 // This will take care of setting the correct layout direction flags
14089 configuration.setLayoutDirection(configuration.locale);
14092 synchronized (this) {
14093 mDebugApp = mOrigDebugApp = debugApp;
14094 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14095 mAlwaysFinishActivities = alwaysFinishActivities;
14096 mSupportsLeanbackOnly = supportsLeanbackOnly;
14097 mForceResizableActivities = forceResizable;
14098 final boolean multiWindowFormEnabled = freeformWindowManagement
14099 || supportsSplitScreenMultiWindow
14100 || supportsPictureInPicture
14101 || supportsMultiDisplay;
14102 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14103 mSupportsMultiWindow = true;
14104 mSupportsFreeformWindowManagement = freeformWindowManagement;
14105 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14106 mSupportsPictureInPicture = supportsPictureInPicture;
14107 mSupportsMultiDisplay = supportsMultiDisplay;
14109 mSupportsMultiWindow = false;
14110 mSupportsFreeformWindowManagement = false;
14111 mSupportsSplitScreenMultiWindow = false;
14112 mSupportsPictureInPicture = false;
14113 mSupportsMultiDisplay = false;
14115 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14116 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14117 // This happens before any activities are started, so we can change global configuration
14119 updateConfigurationLocked(configuration, null, true);
14120 final Configuration globalConfig = getGlobalConfiguration();
14121 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14123 // Load resources only after the current configuration has been set.
14124 final Resources res = mContext.getResources();
14125 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14126 mThumbnailWidth = res.getDimensionPixelSize(
14127 com.android.internal.R.dimen.thumbnail_width);
14128 mThumbnailHeight = res.getDimensionPixelSize(
14129 com.android.internal.R.dimen.thumbnail_height);
14130 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14131 com.android.internal.R.string.config_appsNotReportingCrashes));
14132 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14133 com.android.internal.R.bool.config_customUserSwitchUi);
14134 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14135 mFullscreenThumbnailScale = (float) res
14136 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14137 (float) globalConfig.screenWidthDp;
14139 mFullscreenThumbnailScale = res.getFraction(
14140 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14142 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14146 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14147 traceLog.traceBegin("PhaseActivityManagerReady");
14148 synchronized(this) {
14149 if (mSystemReady) {
14150 // If we're done calling all the receivers, run the next "boot phase" passed in
14151 // by the SystemServer
14152 if (goingCallback != null) {
14153 goingCallback.run();
14158 mLocalDeviceIdleController
14159 = LocalServices.getService(DeviceIdleController.LocalService.class);
14160 mAssistUtils = new AssistUtils(mContext);
14161 mVrController.onSystemReady();
14162 // Make sure we have the current profile info, since it is needed for security checks.
14163 mUserController.onSystemReady();
14164 mRecentTasks.onSystemReadyLocked();
14165 mAppOpsService.systemReady();
14166 mSystemReady = true;
14170 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14171 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14173 } catch (RemoteException e) {}
14175 ArrayList<ProcessRecord> procsToKill = null;
14176 synchronized(mPidsSelfLocked) {
14177 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14178 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14179 if (!isAllowedWhileBooting(proc.info)){
14180 if (procsToKill == null) {
14181 procsToKill = new ArrayList<ProcessRecord>();
14183 procsToKill.add(proc);
14188 synchronized(this) {
14189 if (procsToKill != null) {
14190 for (int i=procsToKill.size()-1; i>=0; i--) {
14191 ProcessRecord proc = procsToKill.get(i);
14192 Slog.i(TAG, "Removing system update proc: " + proc);
14193 removeProcessLocked(proc, true, false, "system update done");
14197 // Now that we have cleaned up any update processes, we
14198 // are ready to start launching real processes and know that
14199 // we won't trample on them any more.
14200 mProcessesReady = true;
14203 Slog.i(TAG, "System now ready");
14204 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14205 SystemClock.uptimeMillis());
14207 synchronized(this) {
14208 // Make sure we have no pre-ready processes sitting around.
14210 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14211 ResolveInfo ri = mContext.getPackageManager()
14212 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14214 CharSequence errorMsg = null;
14216 ActivityInfo ai = ri.activityInfo;
14217 ApplicationInfo app = ai.applicationInfo;
14218 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14219 mTopAction = Intent.ACTION_FACTORY_TEST;
14221 mTopComponent = new ComponentName(app.packageName,
14224 errorMsg = mContext.getResources().getText(
14225 com.android.internal.R.string.factorytest_not_system);
14228 errorMsg = mContext.getResources().getText(
14229 com.android.internal.R.string.factorytest_no_action);
14231 if (errorMsg != null) {
14234 mTopComponent = null;
14235 Message msg = Message.obtain();
14236 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14237 msg.getData().putCharSequence("msg", errorMsg);
14238 mUiHandler.sendMessage(msg);
14243 retrieveSettings();
14244 final int currentUserId;
14245 synchronized (this) {
14246 currentUserId = mUserController.getCurrentUserIdLocked();
14247 readGrantedUriPermissionsLocked();
14250 if (goingCallback != null) goingCallback.run();
14251 traceLog.traceBegin("ActivityManagerStartApps");
14252 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14253 Integer.toString(currentUserId), currentUserId);
14254 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14255 Integer.toString(currentUserId), currentUserId);
14256 mSystemServiceManager.startUser(currentUserId);
14258 synchronized (this) {
14259 // Only start up encryption-aware persistent apps; once user is
14260 // unlocked we'll come back around and start unaware apps
14261 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14263 // Start up initial activity.
14265 // Enable home activity for system user, so that the system can always boot. We don't
14266 // do this when the system user is not setup since the setup wizard should be the one
14267 // to handle home activity in this case.
14268 if (UserManager.isSplitSystemUser() &&
14269 Settings.Secure.getInt(mContext.getContentResolver(),
14270 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14271 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14273 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14274 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14275 UserHandle.USER_SYSTEM);
14276 } catch (RemoteException e) {
14277 throw e.rethrowAsRuntimeException();
14280 startHomeActivityLocked(currentUserId, "systemReady");
14283 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14284 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14285 + " data partition or your device will be unstable.");
14286 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14288 } catch (RemoteException e) {
14291 if (!Build.isBuildConsistent()) {
14292 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14293 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14296 long ident = Binder.clearCallingIdentity();
14298 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14299 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14300 | Intent.FLAG_RECEIVER_FOREGROUND);
14301 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14302 broadcastIntentLocked(null, null, intent,
14303 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14304 null, false, false, MY_PID, SYSTEM_UID,
14306 intent = new Intent(Intent.ACTION_USER_STARTING);
14307 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14308 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14309 broadcastIntentLocked(null, null, intent,
14310 null, new IIntentReceiver.Stub() {
14312 public void performReceive(Intent intent, int resultCode, String data,
14313 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14314 throws RemoteException {
14317 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14318 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14319 } catch (Throwable t) {
14320 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14322 Binder.restoreCallingIdentity(ident);
14324 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14325 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14326 traceLog.traceEnd(); // ActivityManagerStartApps
14327 traceLog.traceEnd(); // PhaseActivityManagerReady
14331 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14332 synchronized (this) {
14333 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14337 void skipCurrentReceiverLocked(ProcessRecord app) {
14338 for (BroadcastQueue queue : mBroadcastQueues) {
14339 queue.skipCurrentReceiverLocked(app);
14344 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14345 * The application process will exit immediately after this call returns.
14346 * @param app object of the crashing app, null for the system server
14347 * @param crashInfo describing the exception
14349 public void handleApplicationCrash(IBinder app,
14350 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14351 ProcessRecord r = findAppProcess(app, "Crash");
14352 final String processName = app == null ? "system_server"
14353 : (r == null ? "unknown" : r.processName);
14355 handleApplicationCrashInner("crash", r, processName, crashInfo);
14358 /* Native crash reporting uses this inner version because it needs to be somewhat
14359 * decoupled from the AM-managed cleanup lifecycle
14361 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14362 ApplicationErrorReport.CrashInfo crashInfo) {
14363 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14364 UserHandle.getUserId(Binder.getCallingUid()), processName,
14365 r == null ? -1 : r.info.flags,
14366 crashInfo.exceptionClassName,
14367 crashInfo.exceptionMessage,
14368 crashInfo.throwFileName,
14369 crashInfo.throwLineNumber);
14371 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14373 mAppErrors.crashApplication(r, crashInfo);
14376 public void handleApplicationStrictModeViolation(
14379 StrictMode.ViolationInfo info) {
14380 ProcessRecord r = findAppProcess(app, "StrictMode");
14385 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14386 Integer stackFingerprint = info.hashCode();
14387 boolean logIt = true;
14388 synchronized (mAlreadyLoggedViolatedStacks) {
14389 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14391 // TODO: sub-sample into EventLog for these, with
14392 // the info.durationMillis? Then we'd get
14393 // the relative pain numbers, without logging all
14394 // the stack traces repeatedly. We'd want to do
14395 // likewise in the client code, which also does
14396 // dup suppression, before the Binder call.
14398 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14399 mAlreadyLoggedViolatedStacks.clear();
14401 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14405 logStrictModeViolationToDropBox(r, info);
14409 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14410 AppErrorResult result = new AppErrorResult();
14411 synchronized (this) {
14412 final long origId = Binder.clearCallingIdentity();
14414 Message msg = Message.obtain();
14415 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14416 HashMap<String, Object> data = new HashMap<String, Object>();
14417 data.put("result", result);
14418 data.put("app", r);
14419 data.put("violationMask", violationMask);
14420 data.put("info", info);
14422 mUiHandler.sendMessage(msg);
14424 Binder.restoreCallingIdentity(origId);
14426 int res = result.get();
14427 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14431 // Depending on the policy in effect, there could be a bunch of
14432 // these in quick succession so we try to batch these together to
14433 // minimize disk writes, number of dropbox entries, and maximize
14434 // compression, by having more fewer, larger records.
14435 private void logStrictModeViolationToDropBox(
14436 ProcessRecord process,
14437 StrictMode.ViolationInfo info) {
14438 if (info == null) {
14441 final boolean isSystemApp = process == null ||
14442 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14443 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14444 final String processName = process == null ? "unknown" : process.processName;
14445 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14446 final DropBoxManager dbox = (DropBoxManager)
14447 mContext.getSystemService(Context.DROPBOX_SERVICE);
14449 // Exit early if the dropbox isn't configured to accept this report type.
14450 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14452 boolean bufferWasEmpty;
14453 boolean needsFlush;
14454 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14455 synchronized (sb) {
14456 bufferWasEmpty = sb.length() == 0;
14457 appendDropBoxProcessHeaders(process, processName, sb);
14458 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14459 sb.append("System-App: ").append(isSystemApp).append("\n");
14460 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14461 if (info.violationNumThisLoop != 0) {
14462 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14464 if (info.numAnimationsRunning != 0) {
14465 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14467 if (info.broadcastIntentAction != null) {
14468 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14470 if (info.durationMillis != -1) {
14471 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14473 if (info.numInstances != -1) {
14474 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14476 if (info.tags != null) {
14477 for (String tag : info.tags) {
14478 sb.append("Span-Tag: ").append(tag).append("\n");
14482 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14483 sb.append(info.crashInfo.stackTrace);
14486 if (info.message != null) {
14487 sb.append(info.message);
14491 // Only buffer up to ~64k. Various logging bits truncate
14493 needsFlush = (sb.length() > 64 * 1024);
14496 // Flush immediately if the buffer's grown too large, or this
14497 // is a non-system app. Non-system apps are isolated with a
14498 // different tag & policy and not batched.
14500 // Batching is useful during internal testing with
14501 // StrictMode settings turned up high. Without batching,
14502 // thousands of separate files could be created on boot.
14503 if (!isSystemApp || needsFlush) {
14504 new Thread("Error dump: " + dropboxTag) {
14506 public void run() {
14508 synchronized (sb) {
14509 report = sb.toString();
14510 sb.delete(0, sb.length());
14513 if (report.length() != 0) {
14514 dbox.addText(dropboxTag, report);
14521 // System app batching:
14522 if (!bufferWasEmpty) {
14523 // An existing dropbox-writing thread is outstanding, so
14524 // we don't need to start it up. The existing thread will
14525 // catch the buffer appends we just did.
14529 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14530 // (After this point, we shouldn't access AMS internal data structures.)
14531 new Thread("Error dump: " + dropboxTag) {
14533 public void run() {
14534 // 5 second sleep to let stacks arrive and be batched together
14536 Thread.sleep(5000); // 5 seconds
14537 } catch (InterruptedException e) {}
14539 String errorReport;
14540 synchronized (mStrictModeBuffer) {
14541 errorReport = mStrictModeBuffer.toString();
14542 if (errorReport.length() == 0) {
14545 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14546 mStrictModeBuffer.trimToSize();
14548 dbox.addText(dropboxTag, errorReport);
14554 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14555 * @param app object of the crashing app, null for the system server
14556 * @param tag reported by the caller
14557 * @param system whether this wtf is coming from the system
14558 * @param crashInfo describing the context of the error
14559 * @return true if the process should exit immediately (WTF is fatal)
14561 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14562 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14563 final int callingUid = Binder.getCallingUid();
14564 final int callingPid = Binder.getCallingPid();
14567 // If this is coming from the system, we could very well have low-level
14568 // system locks held, so we want to do this all asynchronously. And we
14569 // never want this to become fatal, so there is that too.
14570 mHandler.post(new Runnable() {
14571 @Override public void run() {
14572 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14578 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14581 final boolean isFatal = Build.IS_ENG || Settings.Global
14582 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14583 final boolean isSystem = (r == null) || r.persistent;
14585 if (isFatal && !isSystem) {
14586 mAppErrors.crashApplication(r, crashInfo);
14593 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14594 final ApplicationErrorReport.CrashInfo crashInfo) {
14595 final ProcessRecord r = findAppProcess(app, "WTF");
14596 final String processName = app == null ? "system_server"
14597 : (r == null ? "unknown" : r.processName);
14599 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14600 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14602 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14608 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14609 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14611 private ProcessRecord findAppProcess(IBinder app, String reason) {
14616 synchronized (this) {
14617 final int NP = mProcessNames.getMap().size();
14618 for (int ip=0; ip<NP; ip++) {
14619 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14620 final int NA = apps.size();
14621 for (int ia=0; ia<NA; ia++) {
14622 ProcessRecord p = apps.valueAt(ia);
14623 if (p.thread != null && p.thread.asBinder() == app) {
14629 Slog.w(TAG, "Can't find mystery application for " + reason
14630 + " from pid=" + Binder.getCallingPid()
14631 + " uid=" + Binder.getCallingUid() + ": " + app);
14637 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14638 * to append various headers to the dropbox log text.
14640 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14641 StringBuilder sb) {
14642 // Watchdog thread ends up invoking this function (with
14643 // a null ProcessRecord) to add the stack file to dropbox.
14644 // Do not acquire a lock on this (am) in such cases, as it
14645 // could cause a potential deadlock, if and when watchdog
14646 // is invoked due to unavailability of lock on am and it
14647 // would prevent watchdog from killing system_server.
14648 if (process == null) {
14649 sb.append("Process: ").append(processName).append("\n");
14652 // Note: ProcessRecord 'process' is guarded by the service
14653 // instance. (notably process.pkgList, which could otherwise change
14654 // concurrently during execution of this method)
14655 synchronized (this) {
14656 sb.append("Process: ").append(processName).append("\n");
14657 sb.append("PID: ").append(process.pid).append("\n");
14658 int flags = process.info.flags;
14659 IPackageManager pm = AppGlobals.getPackageManager();
14660 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14661 for (int ip=0; ip<process.pkgList.size(); ip++) {
14662 String pkg = process.pkgList.keyAt(ip);
14663 sb.append("Package: ").append(pkg);
14665 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14667 sb.append(" v").append(pi.versionCode);
14668 if (pi.versionName != null) {
14669 sb.append(" (").append(pi.versionName).append(")");
14672 } catch (RemoteException e) {
14673 Slog.e(TAG, "Error getting package info: " + pkg, e);
14677 if (process.info.isInstantApp()) {
14678 sb.append("Instant-App: true\n");
14683 private static String processClass(ProcessRecord process) {
14684 if (process == null || process.pid == MY_PID) {
14685 return "system_server";
14686 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14687 return "system_app";
14693 private volatile long mWtfClusterStart;
14694 private volatile int mWtfClusterCount;
14697 * Write a description of an error (crash, WTF, ANR) to the drop box.
14698 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14699 * @param process which caused the error, null means the system server
14700 * @param activity which triggered the error, null if unknown
14701 * @param parent activity related to the error, null if unknown
14702 * @param subject line related to the error, null if absent
14703 * @param report in long form describing the error, null if absent
14704 * @param dataFile text file to include in the report, null if none
14705 * @param crashInfo giving an application stack trace, null if absent
14707 public void addErrorToDropBox(String eventType,
14708 ProcessRecord process, String processName, ActivityRecord activity,
14709 ActivityRecord parent, String subject,
14710 final String report, final File dataFile,
14711 final ApplicationErrorReport.CrashInfo crashInfo) {
14712 // NOTE -- this must never acquire the ActivityManagerService lock,
14713 // otherwise the watchdog may be prevented from resetting the system.
14715 // Bail early if not published yet
14716 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14717 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14719 // Exit early if the dropbox isn't configured to accept this report type.
14720 final String dropboxTag = processClass(process) + "_" + eventType;
14721 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14723 // Rate-limit how often we're willing to do the heavy lifting below to
14724 // collect and record logs; currently 5 logs per 10 second period.
14725 final long now = SystemClock.elapsedRealtime();
14726 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14727 mWtfClusterStart = now;
14728 mWtfClusterCount = 1;
14730 if (mWtfClusterCount++ >= 5) return;
14733 final StringBuilder sb = new StringBuilder(1024);
14734 appendDropBoxProcessHeaders(process, processName, sb);
14735 if (process != null) {
14736 sb.append("Foreground: ")
14737 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14740 if (activity != null) {
14741 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14743 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14744 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14746 if (parent != null && parent != activity) {
14747 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14749 if (subject != null) {
14750 sb.append("Subject: ").append(subject).append("\n");
14752 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14753 if (Debug.isDebuggerConnected()) {
14754 sb.append("Debugger: Connected\n");
14758 // Do the rest in a worker thread to avoid blocking the caller on I/O
14759 // (After this point, we shouldn't access AMS internal data structures.)
14760 Thread worker = new Thread("Error dump: " + dropboxTag) {
14762 public void run() {
14763 if (report != null) {
14767 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14768 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14769 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14770 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14772 if (dataFile != null && maxDataFileSize > 0) {
14774 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14775 "\n\n[[TRUNCATED]]"));
14776 } catch (IOException e) {
14777 Slog.e(TAG, "Error reading " + dataFile, e);
14780 if (crashInfo != null && crashInfo.stackTrace != null) {
14781 sb.append(crashInfo.stackTrace);
14787 // Merge several logcat streams, and take the last N lines
14788 InputStreamReader input = null;
14790 java.lang.Process logcat = new ProcessBuilder(
14791 "/system/bin/timeout", "-k", "15s", "10s",
14792 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14793 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14794 .redirectErrorStream(true).start();
14796 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14797 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14798 input = new InputStreamReader(logcat.getInputStream());
14801 char[] buf = new char[8192];
14802 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14803 } catch (IOException e) {
14804 Slog.e(TAG, "Error running logcat", e);
14806 if (input != null) try { input.close(); } catch (IOException e) {}
14810 dbox.addText(dropboxTag, sb.toString());
14814 if (process == null) {
14815 // If process is null, we are being called from some internal code
14816 // and may be about to die -- run this synchronously.
14824 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14825 enforceNotIsolatedCaller("getProcessesInErrorState");
14826 // assume our apps are happy - lazy create the list
14827 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14829 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14830 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14831 int userId = UserHandle.getUserId(Binder.getCallingUid());
14833 synchronized (this) {
14835 // iterate across all processes
14836 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14837 ProcessRecord app = mLruProcesses.get(i);
14838 if (!allUsers && app.userId != userId) {
14841 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14842 // This one's in trouble, so we'll generate a report for it
14843 // crashes are higher priority (in case there's a crash *and* an anr)
14844 ActivityManager.ProcessErrorStateInfo report = null;
14845 if (app.crashing) {
14846 report = app.crashingReport;
14847 } else if (app.notResponding) {
14848 report = app.notRespondingReport;
14851 if (report != null) {
14852 if (errList == null) {
14853 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14855 errList.add(report);
14857 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14858 " crashing = " + app.crashing +
14859 " notResponding = " + app.notResponding);
14868 static int procStateToImportance(int procState, int memAdj,
14869 ActivityManager.RunningAppProcessInfo currApp,
14870 int clientTargetSdk) {
14871 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14872 procState, clientTargetSdk);
14873 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14874 currApp.lru = memAdj;
14881 private void fillInProcMemInfo(ProcessRecord app,
14882 ActivityManager.RunningAppProcessInfo outInfo,
14883 int clientTargetSdk) {
14884 outInfo.pid = app.pid;
14885 outInfo.uid = app.info.uid;
14886 if (mHeavyWeightProcess == app) {
14887 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14889 if (app.persistent) {
14890 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14892 if (app.activities.size() > 0) {
14893 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14895 outInfo.lastTrimLevel = app.trimMemoryLevel;
14896 int adj = app.curAdj;
14897 int procState = app.curProcState;
14898 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14899 outInfo.importanceReasonCode = app.adjTypeCode;
14900 outInfo.processState = app.curProcState;
14904 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14905 enforceNotIsolatedCaller("getRunningAppProcesses");
14907 final int callingUid = Binder.getCallingUid();
14908 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14910 // Lazy instantiation of list
14911 List<ActivityManager.RunningAppProcessInfo> runList = null;
14912 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14913 callingUid) == PackageManager.PERMISSION_GRANTED;
14914 final int userId = UserHandle.getUserId(callingUid);
14915 final boolean allUids = isGetTasksAllowed(
14916 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14918 synchronized (this) {
14919 // Iterate across all processes
14920 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14921 ProcessRecord app = mLruProcesses.get(i);
14922 if ((!allUsers && app.userId != userId)
14923 || (!allUids && app.uid != callingUid)) {
14926 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14927 // Generate process state info for running application
14928 ActivityManager.RunningAppProcessInfo currApp =
14929 new ActivityManager.RunningAppProcessInfo(app.processName,
14930 app.pid, app.getPackageList());
14931 fillInProcMemInfo(app, currApp, clientTargetSdk);
14932 if (app.adjSource instanceof ProcessRecord) {
14933 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14934 currApp.importanceReasonImportance =
14935 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14936 app.adjSourceProcState);
14937 } else if (app.adjSource instanceof ActivityRecord) {
14938 ActivityRecord r = (ActivityRecord)app.adjSource;
14939 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14941 if (app.adjTarget instanceof ComponentName) {
14942 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14944 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14945 // + " lru=" + currApp.lru);
14946 if (runList == null) {
14947 runList = new ArrayList<>();
14949 runList.add(currApp);
14957 public List<ApplicationInfo> getRunningExternalApplications() {
14958 enforceNotIsolatedCaller("getRunningExternalApplications");
14959 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14960 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14961 if (runningApps != null && runningApps.size() > 0) {
14962 Set<String> extList = new HashSet<String>();
14963 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14964 if (app.pkgList != null) {
14965 for (String pkg : app.pkgList) {
14970 IPackageManager pm = AppGlobals.getPackageManager();
14971 for (String pkg : extList) {
14973 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14974 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14977 } catch (RemoteException e) {
14985 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14986 enforceNotIsolatedCaller("getMyMemoryState");
14988 final int callingUid = Binder.getCallingUid();
14989 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14991 synchronized (this) {
14992 ProcessRecord proc;
14993 synchronized (mPidsSelfLocked) {
14994 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14996 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15001 public int getMemoryTrimLevel() {
15002 enforceNotIsolatedCaller("getMyMemoryState");
15003 synchronized (this) {
15004 return mLastMemoryLevel;
15009 public void onShellCommand(FileDescriptor in, FileDescriptor out,
15010 FileDescriptor err, String[] args, ShellCallback callback,
15011 ResultReceiver resultReceiver) {
15012 (new ActivityManagerShellCommand(this, false)).exec(
15013 this, in, out, err, args, callback, resultReceiver);
15016 SleepToken acquireSleepToken(String tag, int displayId) {
15017 synchronized (this) {
15018 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15019 updateSleepIfNeededLocked();
15025 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15026 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15028 boolean dumpAll = false;
15029 boolean dumpClient = false;
15030 boolean dumpCheckin = false;
15031 boolean dumpCheckinFormat = false;
15032 boolean dumpVisibleStacksOnly = false;
15033 boolean dumpFocusedStackOnly = false;
15034 String dumpPackage = null;
15037 while (opti < args.length) {
15038 String opt = args[opti];
15039 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15043 if ("-a".equals(opt)) {
15045 } else if ("-c".equals(opt)) {
15047 } else if ("-v".equals(opt)) {
15048 dumpVisibleStacksOnly = true;
15049 } else if ("-f".equals(opt)) {
15050 dumpFocusedStackOnly = true;
15051 } else if ("-p".equals(opt)) {
15052 if (opti < args.length) {
15053 dumpPackage = args[opti];
15056 pw.println("Error: -p option requires package argument");
15060 } else if ("--checkin".equals(opt)) {
15061 dumpCheckin = dumpCheckinFormat = true;
15062 } else if ("-C".equals(opt)) {
15063 dumpCheckinFormat = true;
15064 } else if ("-h".equals(opt)) {
15065 ActivityManagerShellCommand.dumpHelp(pw, true);
15068 pw.println("Unknown argument: " + opt + "; use -h for help");
15072 long origId = Binder.clearCallingIdentity();
15073 boolean more = false;
15074 // Is the caller requesting to dump a particular piece of data?
15075 if (opti < args.length) {
15076 String cmd = args[opti];
15078 if ("activities".equals(cmd) || "a".equals(cmd)) {
15079 synchronized (this) {
15080 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15082 } else if ("lastanr".equals(cmd)) {
15083 synchronized (this) {
15084 dumpLastANRLocked(pw);
15086 } else if ("starter".equals(cmd)) {
15087 synchronized (this) {
15088 dumpActivityStarterLocked(pw, dumpPackage);
15090 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15091 synchronized (this) {
15092 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15094 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15097 if (opti >= args.length) {
15099 newArgs = EMPTY_STRING_ARRAY;
15101 dumpPackage = args[opti];
15103 newArgs = new String[args.length - opti];
15104 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15105 args.length - opti);
15107 synchronized (this) {
15108 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15110 } else if ("broadcast-stats".equals(cmd)) {
15113 if (opti >= args.length) {
15115 newArgs = EMPTY_STRING_ARRAY;
15117 dumpPackage = args[opti];
15119 newArgs = new String[args.length - opti];
15120 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15121 args.length - opti);
15123 synchronized (this) {
15124 if (dumpCheckinFormat) {
15125 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15128 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15131 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15134 if (opti >= args.length) {
15136 newArgs = EMPTY_STRING_ARRAY;
15138 dumpPackage = args[opti];
15140 newArgs = new String[args.length - opti];
15141 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15142 args.length - opti);
15144 synchronized (this) {
15145 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15147 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15150 if (opti >= args.length) {
15152 newArgs = EMPTY_STRING_ARRAY;
15154 dumpPackage = args[opti];
15156 newArgs = new String[args.length - opti];
15157 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15158 args.length - opti);
15160 synchronized (this) {
15161 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15163 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15164 synchronized (this) {
15165 dumpOomLocked(fd, pw, args, opti, true);
15167 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15168 synchronized (this) {
15169 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15171 } else if ("provider".equals(cmd)) {
15174 if (opti >= args.length) {
15176 newArgs = EMPTY_STRING_ARRAY;
15180 newArgs = new String[args.length - opti];
15181 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15183 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15184 pw.println("No providers match: " + name);
15185 pw.println("Use -h for help.");
15187 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15188 synchronized (this) {
15189 dumpProvidersLocked(fd, pw, args, opti, true, null);
15191 } else if ("service".equals(cmd)) {
15194 if (opti >= args.length) {
15196 newArgs = EMPTY_STRING_ARRAY;
15200 newArgs = new String[args.length - opti];
15201 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15202 args.length - opti);
15204 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15205 pw.println("No services match: " + name);
15206 pw.println("Use -h for help.");
15208 } else if ("package".equals(cmd)) {
15210 if (opti >= args.length) {
15211 pw.println("package: no package name specified");
15212 pw.println("Use -h for help.");
15214 dumpPackage = args[opti];
15216 newArgs = new String[args.length - opti];
15217 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15218 args.length - opti);
15223 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15224 synchronized (this) {
15225 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15227 } else if ("settings".equals(cmd)) {
15228 synchronized (this) {
15229 mConstants.dump(pw);
15231 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15233 ActiveServices.ServiceDumper dumper;
15234 synchronized (this) {
15235 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15238 dumper.dumpWithClient();
15240 synchronized (this) {
15241 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15242 dumpPackage).dumpLocked();
15245 } else if ("locks".equals(cmd)) {
15246 LockGuard.dump(fd, pw, args);
15248 // Dumping a single activity?
15249 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15250 dumpFocusedStackOnly)) {
15251 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15252 int res = shell.exec(this, null, fd, null, args, null,
15253 new ResultReceiver(null));
15255 pw.println("Bad activity command, or no activities match: " + cmd);
15256 pw.println("Use -h for help.");
15261 Binder.restoreCallingIdentity(origId);
15266 // No piece of data specified, dump everything.
15267 if (dumpCheckinFormat) {
15268 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15269 } else if (dumpClient) {
15270 ActiveServices.ServiceDumper sdumper;
15271 synchronized (this) {
15272 mConstants.dump(pw);
15275 pw.println("-------------------------------------------------------------------------------");
15277 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15280 pw.println("-------------------------------------------------------------------------------");
15282 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15285 pw.println("-------------------------------------------------------------------------------");
15287 if (dumpAll || dumpPackage != null) {
15288 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15291 pw.println("-------------------------------------------------------------------------------");
15294 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15297 pw.println("-------------------------------------------------------------------------------");
15299 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15302 pw.println("-------------------------------------------------------------------------------");
15304 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15307 sdumper.dumpWithClient();
15309 synchronized (this) {
15311 pw.println("-------------------------------------------------------------------------------");
15313 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15316 pw.println("-------------------------------------------------------------------------------");
15318 dumpLastANRLocked(pw);
15321 pw.println("-------------------------------------------------------------------------------");
15323 dumpActivityStarterLocked(pw, dumpPackage);
15326 pw.println("-------------------------------------------------------------------------------");
15328 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15329 if (mAssociations.size() > 0) {
15332 pw.println("-------------------------------------------------------------------------------");
15334 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15338 pw.println("-------------------------------------------------------------------------------");
15340 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15344 synchronized (this) {
15345 mConstants.dump(pw);
15348 pw.println("-------------------------------------------------------------------------------");
15350 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15353 pw.println("-------------------------------------------------------------------------------");
15355 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15358 pw.println("-------------------------------------------------------------------------------");
15360 if (dumpAll || dumpPackage != null) {
15361 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15364 pw.println("-------------------------------------------------------------------------------");
15367 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15370 pw.println("-------------------------------------------------------------------------------");
15372 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15375 pw.println("-------------------------------------------------------------------------------");
15377 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15381 pw.println("-------------------------------------------------------------------------------");
15383 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15386 pw.println("-------------------------------------------------------------------------------");
15388 dumpLastANRLocked(pw);
15391 pw.println("-------------------------------------------------------------------------------");
15393 dumpActivityStarterLocked(pw, dumpPackage);
15396 pw.println("-------------------------------------------------------------------------------");
15398 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15399 if (mAssociations.size() > 0) {
15402 pw.println("-------------------------------------------------------------------------------");
15404 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15408 pw.println("-------------------------------------------------------------------------------");
15410 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15413 Binder.restoreCallingIdentity(origId);
15416 private void dumpLastANRLocked(PrintWriter pw) {
15417 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15418 if (mLastANRState == null) {
15419 pw.println(" <no ANR has occurred since boot>");
15421 pw.println(mLastANRState);
15425 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15426 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15427 mActivityStarter.dump(pw, "", dumpPackage);
15430 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15431 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15432 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15433 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15436 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15437 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15438 pw.println(header);
15440 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15442 boolean needSep = printedAnything;
15444 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15445 mStackSupervisor.getResumedActivityLocked(),
15446 dumpPackage, needSep, " ResumedActivity: ");
15448 printedAnything = true;
15452 if (dumpPackage == null) {
15456 printedAnything = true;
15457 mStackSupervisor.dump(pw, " ");
15460 if (!printedAnything) {
15461 pw.println(" (nothing)");
15465 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15466 int opti, boolean dumpAll, String dumpPackage) {
15467 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15469 boolean printedAnything = false;
15471 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15472 boolean printedHeader = false;
15474 final int N = mRecentTasks.size();
15475 for (int i=0; i<N; i++) {
15476 TaskRecord tr = mRecentTasks.get(i);
15477 if (dumpPackage != null) {
15478 if (tr.realActivity == null ||
15479 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15483 if (!printedHeader) {
15484 pw.println(" Recent tasks:");
15485 printedHeader = true;
15486 printedAnything = true;
15488 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15491 mRecentTasks.get(i).dump(pw, " ");
15496 if (!printedAnything) {
15497 pw.println(" (nothing)");
15501 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15502 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15503 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15506 if (dumpPackage != null) {
15507 IPackageManager pm = AppGlobals.getPackageManager();
15509 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15510 } catch (RemoteException e) {
15514 boolean printedAnything = false;
15516 final long now = SystemClock.uptimeMillis();
15518 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15519 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15520 = mAssociations.valueAt(i1);
15521 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15522 SparseArray<ArrayMap<String, Association>> sourceUids
15523 = targetComponents.valueAt(i2);
15524 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15525 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15526 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15527 Association ass = sourceProcesses.valueAt(i4);
15528 if (dumpPackage != null) {
15529 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15530 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15534 printedAnything = true;
15536 pw.print(ass.mTargetProcess);
15538 UserHandle.formatUid(pw, ass.mTargetUid);
15540 pw.print(ass.mSourceProcess);
15542 UserHandle.formatUid(pw, ass.mSourceUid);
15545 pw.print(ass.mTargetComponent.flattenToShortString());
15548 long dur = ass.mTime;
15549 if (ass.mNesting > 0) {
15550 dur += now - ass.mStartTime;
15552 TimeUtils.formatDuration(dur, pw);
15554 pw.print(ass.mCount);
15555 pw.print(" times)");
15557 for (int i=0; i<ass.mStateTimes.length; i++) {
15558 long amt = ass.mStateTimes[i];
15559 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15560 amt += now - ass.mLastStateUptime;
15564 pw.print(ProcessList.makeProcStateString(
15565 i + ActivityManager.MIN_PROCESS_STATE));
15567 TimeUtils.formatDuration(amt, pw);
15568 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15574 if (ass.mNesting > 0) {
15575 pw.print(" Currently active: ");
15576 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15585 if (!printedAnything) {
15586 pw.println(" (nothing)");
15590 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15591 String header, boolean needSep) {
15592 boolean printed = false;
15593 int whichAppId = -1;
15594 if (dumpPackage != null) {
15596 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15598 whichAppId = UserHandle.getAppId(info.uid);
15599 } catch (NameNotFoundException e) {
15600 e.printStackTrace();
15603 for (int i=0; i<uids.size(); i++) {
15604 UidRecord uidRec = uids.valueAt(i);
15605 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15614 pw.println(header);
15617 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15618 pw.print(": "); pw.println(uidRec);
15623 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15624 int opti, boolean dumpAll, String dumpPackage) {
15625 boolean needSep = false;
15626 boolean printedAnything = false;
15629 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15632 final int NP = mProcessNames.getMap().size();
15633 for (int ip=0; ip<NP; ip++) {
15634 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15635 final int NA = procs.size();
15636 for (int ia=0; ia<NA; ia++) {
15637 ProcessRecord r = procs.valueAt(ia);
15638 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15642 pw.println(" All known processes:");
15644 printedAnything = true;
15646 pw.print(r.persistent ? " *PERS*" : " *APP*");
15647 pw.print(" UID "); pw.print(procs.keyAt(ia));
15648 pw.print(" "); pw.println(r);
15650 if (r.persistent) {
15657 if (mIsolatedProcesses.size() > 0) {
15658 boolean printed = false;
15659 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15660 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15661 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15668 pw.println(" Isolated process list (sorted by uid):");
15669 printedAnything = true;
15673 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15678 if (mActiveInstrumentation.size() > 0) {
15679 boolean printed = false;
15680 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15681 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15682 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15683 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15690 pw.println(" Active instrumentation:");
15691 printedAnything = true;
15695 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15701 if (mActiveUids.size() > 0) {
15702 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15703 printedAnything = needSep = true;
15707 if (mValidateUids.size() > 0) {
15708 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15709 printedAnything = needSep = true;
15714 if (mLruProcesses.size() > 0) {
15718 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15719 pw.print(" total, non-act at ");
15720 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15721 pw.print(", non-svc at ");
15722 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15724 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15726 printedAnything = true;
15729 if (dumpAll || dumpPackage != null) {
15730 synchronized (mPidsSelfLocked) {
15731 boolean printed = false;
15732 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15733 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15734 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15738 if (needSep) pw.println();
15740 pw.println(" PID mappings:");
15742 printedAnything = true;
15744 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15745 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15750 if (mImportantProcesses.size() > 0) {
15751 synchronized (mPidsSelfLocked) {
15752 boolean printed = false;
15753 for (int i = 0; i< mImportantProcesses.size(); i++) {
15754 ProcessRecord r = mPidsSelfLocked.get(
15755 mImportantProcesses.valueAt(i).pid);
15756 if (dumpPackage != null && (r == null
15757 || !r.pkgList.containsKey(dumpPackage))) {
15761 if (needSep) pw.println();
15763 pw.println(" Foreground Processes:");
15765 printedAnything = true;
15767 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15768 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15773 if (mPersistentStartingProcesses.size() > 0) {
15774 if (needSep) pw.println();
15776 printedAnything = true;
15777 pw.println(" Persisent processes that are starting:");
15778 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15779 "Starting Norm", "Restarting PERS", dumpPackage);
15782 if (mRemovedProcesses.size() > 0) {
15783 if (needSep) pw.println();
15785 printedAnything = true;
15786 pw.println(" Processes that are being removed:");
15787 dumpProcessList(pw, this, mRemovedProcesses, " ",
15788 "Removed Norm", "Removed PERS", dumpPackage);
15791 if (mProcessesOnHold.size() > 0) {
15792 if (needSep) pw.println();
15794 printedAnything = true;
15795 pw.println(" Processes that are on old until the system is ready:");
15796 dumpProcessList(pw, this, mProcessesOnHold, " ",
15797 "OnHold Norm", "OnHold PERS", dumpPackage);
15800 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15802 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15804 printedAnything = true;
15807 if (dumpPackage == null) {
15810 mUserController.dump(pw, dumpAll);
15812 if (mHomeProcess != null && (dumpPackage == null
15813 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15818 pw.println(" mHomeProcess: " + mHomeProcess);
15820 if (mPreviousProcess != null && (dumpPackage == null
15821 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15826 pw.println(" mPreviousProcess: " + mPreviousProcess);
15829 StringBuilder sb = new StringBuilder(128);
15830 sb.append(" mPreviousProcessVisibleTime: ");
15831 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15834 if (mHeavyWeightProcess != null && (dumpPackage == null
15835 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15840 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15842 if (dumpPackage == null) {
15843 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15844 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15847 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15848 if (mCompatModePackages.getPackages().size() > 0) {
15849 boolean printed = false;
15850 for (Map.Entry<String, Integer> entry
15851 : mCompatModePackages.getPackages().entrySet()) {
15852 String pkg = entry.getKey();
15853 int mode = entry.getValue();
15854 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15858 pw.println(" mScreenCompatPackages:");
15861 pw.print(" "); pw.print(pkg); pw.print(": ");
15862 pw.print(mode); pw.println();
15865 final int NI = mUidObservers.getRegisteredCallbackCount();
15866 boolean printed = false;
15867 for (int i=0; i<NI; i++) {
15868 final UidObserverRegistration reg = (UidObserverRegistration)
15869 mUidObservers.getRegisteredCallbackCookie(i);
15870 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15872 pw.println(" mUidObservers:");
15875 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15876 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15877 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15880 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15883 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15886 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15887 pw.print(" STATE");
15888 pw.print(" (cut="); pw.print(reg.cutpoint);
15892 if (reg.lastProcStates != null) {
15893 final int NJ = reg.lastProcStates.size();
15894 for (int j=0; j<NJ; j++) {
15895 pw.print(" Last ");
15896 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15897 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15902 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15903 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15904 if (mPendingTempWhitelist.size() > 0) {
15905 pw.println(" mPendingTempWhitelist:");
15906 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15907 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15909 UserHandle.formatUid(pw, ptw.targetUid);
15911 TimeUtils.formatDuration(ptw.duration, pw);
15913 pw.println(ptw.tag);
15917 if (dumpPackage == null) {
15918 pw.println(" mWakefulness="
15919 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15920 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
15921 pw.println(" mSleeping=" + mSleeping);
15922 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15923 if (mRunningVoice != null) {
15924 pw.println(" mRunningVoice=" + mRunningVoice);
15925 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15928 pw.println(" mVrController=" + mVrController);
15929 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15930 || mOrigWaitForDebugger) {
15931 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15932 || dumpPackage.equals(mOrigDebugApp)) {
15937 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15938 + " mDebugTransient=" + mDebugTransient
15939 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15942 if (mCurAppTimeTracker != null) {
15943 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15945 if (mMemWatchProcesses.getMap().size() > 0) {
15946 pw.println(" Mem watch processes:");
15947 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15948 = mMemWatchProcesses.getMap();
15949 for (int i=0; i<procs.size(); i++) {
15950 final String proc = procs.keyAt(i);
15951 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15952 for (int j=0; j<uids.size(); j++) {
15957 StringBuilder sb = new StringBuilder();
15958 sb.append(" ").append(proc).append('/');
15959 UserHandle.formatUid(sb, uids.keyAt(j));
15960 Pair<Long, String> val = uids.valueAt(j);
15961 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15962 if (val.second != null) {
15963 sb.append(", report to ").append(val.second);
15965 pw.println(sb.toString());
15968 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15969 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15970 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15971 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15973 if (mTrackAllocationApp != null) {
15974 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15979 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15982 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15983 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15984 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15989 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15990 if (mProfilerInfo != null) {
15991 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
15992 mProfilerInfo.profileFd);
15993 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
15994 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
15995 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
15996 pw.println(" mProfileType=" + mProfileType);
16000 if (mNativeDebuggingApp != null) {
16001 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16006 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
16009 if (dumpPackage == null) {
16010 if (mAlwaysFinishActivities) {
16011 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16013 if (mController != null) {
16014 pw.println(" mController=" + mController
16015 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16018 pw.println(" Total persistent processes: " + numPers);
16019 pw.println(" mProcessesReady=" + mProcessesReady
16020 + " mSystemReady=" + mSystemReady
16021 + " mBooted=" + mBooted
16022 + " mFactoryTest=" + mFactoryTest);
16023 pw.println(" mBooting=" + mBooting
16024 + " mCallFinishBooting=" + mCallFinishBooting
16025 + " mBootAnimationComplete=" + mBootAnimationComplete);
16026 pw.print(" mLastPowerCheckUptime=");
16027 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16029 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16030 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16031 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16032 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
16033 + " (" + mLruProcesses.size() + " total)"
16034 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16035 + " mNumServiceProcs=" + mNumServiceProcs
16036 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16037 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
16038 + " mLastMemoryLevel=" + mLastMemoryLevel
16039 + " mLastNumProcesses=" + mLastNumProcesses);
16040 long now = SystemClock.uptimeMillis();
16041 pw.print(" mLastIdleTime=");
16042 TimeUtils.formatDuration(now, mLastIdleTime, pw);
16043 pw.print(" mLowRamSinceLastIdle=");
16044 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16049 if (!printedAnything) {
16050 pw.println(" (nothing)");
16054 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16055 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16056 if (mProcessesToGc.size() > 0) {
16057 boolean printed = false;
16058 long now = SystemClock.uptimeMillis();
16059 for (int i=0; i<mProcessesToGc.size(); i++) {
16060 ProcessRecord proc = mProcessesToGc.get(i);
16061 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16065 if (needSep) pw.println();
16067 pw.println(" Processes that are waiting to GC:");
16070 pw.print(" Process "); pw.println(proc);
16071 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16072 pw.print(", last gced=");
16073 pw.print(now-proc.lastRequestedGc);
16074 pw.print(" ms ago, last lowMem=");
16075 pw.print(now-proc.lastLowMemory);
16076 pw.println(" ms ago");
16083 void printOomLevel(PrintWriter pw, String name, int adj) {
16087 if (adj < 10) pw.print(' ');
16089 if (adj > -10) pw.print(' ');
16095 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16099 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16100 int opti, boolean dumpAll) {
16101 boolean needSep = false;
16103 if (mLruProcesses.size() > 0) {
16104 if (needSep) pw.println();
16106 pw.println(" OOM levels:");
16107 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16108 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16109 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16110 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16111 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16112 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16113 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16114 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16115 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16116 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16117 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16118 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16119 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16120 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16122 if (needSep) pw.println();
16123 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16124 pw.print(" total, non-act at ");
16125 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16126 pw.print(", non-svc at ");
16127 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16129 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16133 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16136 pw.println(" mHomeProcess: " + mHomeProcess);
16137 pw.println(" mPreviousProcess: " + mPreviousProcess);
16138 if (mHeavyWeightProcess != null) {
16139 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16146 * There are three ways to call this:
16147 * - no provider specified: dump all the providers
16148 * - a flattened component name that matched an existing provider was specified as the
16149 * first arg: dump that one provider
16150 * - the first arg isn't the flattened component name of an existing provider:
16151 * dump all providers whose component contains the first arg as a substring
16153 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16154 int opti, boolean dumpAll) {
16155 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16158 static class ItemMatcher {
16159 ArrayList<ComponentName> components;
16160 ArrayList<String> strings;
16161 ArrayList<Integer> objects;
16168 void build(String name) {
16169 ComponentName componentName = ComponentName.unflattenFromString(name);
16170 if (componentName != null) {
16171 if (components == null) {
16172 components = new ArrayList<ComponentName>();
16174 components.add(componentName);
16178 // Not a '/' separated full component name; maybe an object ID?
16180 objectId = Integer.parseInt(name, 16);
16181 if (objects == null) {
16182 objects = new ArrayList<Integer>();
16184 objects.add(objectId);
16186 } catch (RuntimeException e) {
16187 // Not an integer; just do string match.
16188 if (strings == null) {
16189 strings = new ArrayList<String>();
16197 int build(String[] args, int opti) {
16198 for (; opti<args.length; opti++) {
16199 String name = args[opti];
16200 if ("--".equals(name)) {
16208 boolean match(Object object, ComponentName comp) {
16212 if (components != null) {
16213 for (int i=0; i<components.size(); i++) {
16214 if (components.get(i).equals(comp)) {
16219 if (objects != null) {
16220 for (int i=0; i<objects.size(); i++) {
16221 if (System.identityHashCode(object) == objects.get(i)) {
16226 if (strings != null) {
16227 String flat = comp.flattenToString();
16228 for (int i=0; i<strings.size(); i++) {
16229 if (flat.contains(strings.get(i))) {
16239 * There are three things that cmd can be:
16240 * - a flattened component name that matches an existing activity
16241 * - the cmd arg isn't the flattened component name of an existing activity:
16242 * dump all activity whose component contains the cmd as a substring
16243 * - A hex number of the ActivityRecord object instance.
16245 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16246 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16248 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16249 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16250 ArrayList<ActivityRecord> activities;
16252 synchronized (this) {
16253 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16254 dumpFocusedStackOnly);
16257 if (activities.size() <= 0) {
16261 String[] newArgs = new String[args.length - opti];
16262 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16264 TaskRecord lastTask = null;
16265 boolean needSep = false;
16266 for (int i=activities.size()-1; i>=0; i--) {
16267 ActivityRecord r = activities.get(i);
16272 synchronized (this) {
16273 final TaskRecord task = r.getTask();
16274 if (lastTask != task) {
16276 pw.print("TASK "); pw.print(lastTask.affinity);
16277 pw.print(" id="); pw.print(lastTask.taskId);
16278 pw.print(" userId="); pw.println(lastTask.userId);
16280 lastTask.dump(pw, " ");
16284 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16290 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16291 * there is a thread associated with the activity.
16293 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16294 final ActivityRecord r, String[] args, boolean dumpAll) {
16295 String innerPrefix = prefix + " ";
16296 synchronized (this) {
16297 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16298 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16300 if (r.app != null) pw.println(r.app.pid);
16301 else pw.println("(not running)");
16303 r.dump(pw, innerPrefix);
16306 if (r.app != null && r.app.thread != null) {
16307 // flush anything that is already in the PrintWriter since the thread is going
16308 // to write to the file descriptor directly
16311 TransferPipe tp = new TransferPipe();
16313 r.app.thread.dumpActivity(tp.getWriteFd(),
16314 r.appToken, innerPrefix, args);
16319 } catch (IOException e) {
16320 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16321 } catch (RemoteException e) {
16322 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16327 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16328 int opti, boolean dumpAll, String dumpPackage) {
16329 boolean needSep = false;
16330 boolean onlyHistory = false;
16331 boolean printedAnything = false;
16333 if ("history".equals(dumpPackage)) {
16334 if (opti < args.length && "-s".equals(args[opti])) {
16337 onlyHistory = true;
16338 dumpPackage = null;
16341 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16342 if (!onlyHistory && dumpAll) {
16343 if (mRegisteredReceivers.size() > 0) {
16344 boolean printed = false;
16345 Iterator it = mRegisteredReceivers.values().iterator();
16346 while (it.hasNext()) {
16347 ReceiverList r = (ReceiverList)it.next();
16348 if (dumpPackage != null && (r.app == null ||
16349 !dumpPackage.equals(r.app.info.packageName))) {
16353 pw.println(" Registered Receivers:");
16356 printedAnything = true;
16358 pw.print(" * "); pw.println(r);
16363 if (mReceiverResolver.dump(pw, needSep ?
16364 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16365 " ", dumpPackage, false, false)) {
16367 printedAnything = true;
16371 for (BroadcastQueue q : mBroadcastQueues) {
16372 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16373 printedAnything |= needSep;
16378 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16379 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16384 printedAnything = true;
16385 pw.print(" Sticky broadcasts for user ");
16386 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16387 StringBuilder sb = new StringBuilder(128);
16388 for (Map.Entry<String, ArrayList<Intent>> ent
16389 : mStickyBroadcasts.valueAt(user).entrySet()) {
16390 pw.print(" * Sticky action "); pw.print(ent.getKey());
16393 ArrayList<Intent> intents = ent.getValue();
16394 final int N = intents.size();
16395 for (int i=0; i<N; i++) {
16397 sb.append(" Intent: ");
16398 intents.get(i).toShortString(sb, false, true, false, false);
16399 pw.println(sb.toString());
16400 Bundle bundle = intents.get(i).getExtras();
16401 if (bundle != null) {
16403 pw.println(bundle.toString());
16413 if (!onlyHistory && dumpAll) {
16415 for (BroadcastQueue queue : mBroadcastQueues) {
16416 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16417 + queue.mBroadcastsScheduled);
16419 pw.println(" mHandler:");
16420 mHandler.dump(new PrintWriterPrinter(pw), " ");
16422 printedAnything = true;
16425 if (!printedAnything) {
16426 pw.println(" (nothing)");
16430 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16431 int opti, boolean dumpAll, String dumpPackage) {
16432 if (mCurBroadcastStats == null) {
16436 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16437 final long now = SystemClock.elapsedRealtime();
16438 if (mLastBroadcastStats != null) {
16439 pw.print(" Last stats (from ");
16440 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16442 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16444 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16445 - mLastBroadcastStats.mStartUptime, pw);
16446 pw.println(" uptime):");
16447 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16448 pw.println(" (nothing)");
16452 pw.print(" Current stats (from ");
16453 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16454 pw.print(" to now, ");
16455 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16456 - mCurBroadcastStats.mStartUptime, pw);
16457 pw.println(" uptime):");
16458 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16459 pw.println(" (nothing)");
16463 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16464 int opti, boolean fullCheckin, String dumpPackage) {
16465 if (mCurBroadcastStats == null) {
16469 if (mLastBroadcastStats != null) {
16470 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16472 mLastBroadcastStats = null;
16476 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16478 mCurBroadcastStats = null;
16482 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16483 int opti, boolean dumpAll, String dumpPackage) {
16485 boolean printedAnything = false;
16487 ItemMatcher matcher = new ItemMatcher();
16488 matcher.build(args, opti);
16490 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16492 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16493 printedAnything |= needSep;
16495 if (mLaunchingProviders.size() > 0) {
16496 boolean printed = false;
16497 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16498 ContentProviderRecord r = mLaunchingProviders.get(i);
16499 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16503 if (needSep) pw.println();
16505 pw.println(" Launching content providers:");
16507 printedAnything = true;
16509 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16514 if (!printedAnything) {
16515 pw.println(" (nothing)");
16519 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16520 int opti, boolean dumpAll, String dumpPackage) {
16521 boolean needSep = false;
16522 boolean printedAnything = false;
16524 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16526 if (mGrantedUriPermissions.size() > 0) {
16527 boolean printed = false;
16529 if (dumpPackage != null) {
16531 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16532 MATCH_ANY_USER, 0);
16533 } catch (NameNotFoundException e) {
16537 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16538 int uid = mGrantedUriPermissions.keyAt(i);
16539 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16542 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16544 if (needSep) pw.println();
16546 pw.println(" Granted Uri Permissions:");
16548 printedAnything = true;
16550 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16551 for (UriPermission perm : perms.values()) {
16552 pw.print(" "); pw.println(perm);
16554 perm.dump(pw, " ");
16560 if (!printedAnything) {
16561 pw.println(" (nothing)");
16565 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16566 int opti, boolean dumpAll, String dumpPackage) {
16567 boolean printed = false;
16569 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16571 if (mIntentSenderRecords.size() > 0) {
16572 // Organize these by package name, so they are easier to read.
16573 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16574 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16575 final Iterator<WeakReference<PendingIntentRecord>> it
16576 = mIntentSenderRecords.values().iterator();
16577 while (it.hasNext()) {
16578 WeakReference<PendingIntentRecord> ref = it.next();
16579 PendingIntentRecord rec = ref != null ? ref.get() : null;
16584 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16587 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16588 if (list == null) {
16589 list = new ArrayList<>();
16590 byPackage.put(rec.key.packageName, list);
16594 for (int i = 0; i < byPackage.size(); i++) {
16595 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16597 pw.print(" * "); pw.print(byPackage.keyAt(i));
16598 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16599 for (int j = 0; j < intents.size(); j++) {
16600 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16602 intents.get(j).dump(pw, " ");
16606 if (weakRefs.size() > 0) {
16608 pw.println(" * WEAK REFS:");
16609 for (int i = 0; i < weakRefs.size(); i++) {
16610 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16616 pw.println(" (nothing)");
16620 private static final int dumpProcessList(PrintWriter pw,
16621 ActivityManagerService service, List list,
16622 String prefix, String normalLabel, String persistentLabel,
16623 String dumpPackage) {
16625 final int N = list.size()-1;
16626 for (int i=N; i>=0; i--) {
16627 ProcessRecord r = (ProcessRecord)list.get(i);
16628 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16631 pw.println(String.format("%s%s #%2d: %s",
16632 prefix, (r.persistent ? persistentLabel : normalLabel),
16634 if (r.persistent) {
16641 private static final boolean dumpProcessOomList(PrintWriter pw,
16642 ActivityManagerService service, List<ProcessRecord> origList,
16643 String prefix, String normalLabel, String persistentLabel,
16644 boolean inclDetails, String dumpPackage) {
16646 ArrayList<Pair<ProcessRecord, Integer>> list
16647 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16648 for (int i=0; i<origList.size(); i++) {
16649 ProcessRecord r = origList.get(i);
16650 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16653 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16656 if (list.size() <= 0) {
16660 Comparator<Pair<ProcessRecord, Integer>> comparator
16661 = new Comparator<Pair<ProcessRecord, Integer>>() {
16663 public int compare(Pair<ProcessRecord, Integer> object1,
16664 Pair<ProcessRecord, Integer> object2) {
16665 if (object1.first.setAdj != object2.first.setAdj) {
16666 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16668 if (object1.first.setProcState != object2.first.setProcState) {
16669 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16671 if (object1.second.intValue() != object2.second.intValue()) {
16672 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16678 Collections.sort(list, comparator);
16680 final long curUptime = SystemClock.uptimeMillis();
16681 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16683 for (int i=list.size()-1; i>=0; i--) {
16684 ProcessRecord r = list.get(i).first;
16685 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16687 switch (r.setSchedGroup) {
16688 case ProcessList.SCHED_GROUP_BACKGROUND:
16691 case ProcessList.SCHED_GROUP_DEFAULT:
16694 case ProcessList.SCHED_GROUP_TOP_APP:
16702 if (r.foregroundActivities) {
16704 } else if (r.foregroundServices) {
16709 String procState = ProcessList.makeProcStateString(r.curProcState);
16711 pw.print(r.persistent ? persistentLabel : normalLabel);
16713 int num = (origList.size()-1)-list.get(i).second;
16714 if (num < 10) pw.print(' ');
16719 pw.print(schedGroup);
16721 pw.print(foreground);
16723 pw.print(procState);
16725 if (r.trimMemoryLevel < 10) pw.print(' ');
16726 pw.print(r.trimMemoryLevel);
16728 pw.print(r.toShortString());
16730 pw.print(r.adjType);
16732 if (r.adjSource != null || r.adjTarget != null) {
16735 if (r.adjTarget instanceof ComponentName) {
16736 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16737 } else if (r.adjTarget != null) {
16738 pw.print(r.adjTarget.toString());
16740 pw.print("{null}");
16743 if (r.adjSource instanceof ProcessRecord) {
16745 pw.print(((ProcessRecord)r.adjSource).toShortString());
16747 } else if (r.adjSource != null) {
16748 pw.println(r.adjSource.toString());
16750 pw.println("{null}");
16756 pw.print("oom: max="); pw.print(r.maxAdj);
16757 pw.print(" curRaw="); pw.print(r.curRawAdj);
16758 pw.print(" setRaw="); pw.print(r.setRawAdj);
16759 pw.print(" cur="); pw.print(r.curAdj);
16760 pw.print(" set="); pw.println(r.setAdj);
16763 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16764 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16765 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16766 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16767 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16771 pw.print("cached="); pw.print(r.cached);
16772 pw.print(" empty="); pw.print(r.empty);
16773 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16775 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16776 if (r.lastCpuTime != 0) {
16777 long timeUsed = r.curCpuTime - r.lastCpuTime;
16780 pw.print("run cpu over ");
16781 TimeUtils.formatDuration(uptimeSince, pw);
16782 pw.print(" used ");
16783 TimeUtils.formatDuration(timeUsed, pw);
16785 pw.print((timeUsed*100)/uptimeSince);
16794 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16796 ArrayList<ProcessRecord> procs;
16797 synchronized (this) {
16798 if (args != null && args.length > start
16799 && args[start].charAt(0) != '-') {
16800 procs = new ArrayList<ProcessRecord>();
16803 pid = Integer.parseInt(args[start]);
16804 } catch (NumberFormatException e) {
16806 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16807 ProcessRecord proc = mLruProcesses.get(i);
16808 if (proc.pid == pid) {
16810 } else if (allPkgs && proc.pkgList != null
16811 && proc.pkgList.containsKey(args[start])) {
16813 } else if (proc.processName.equals(args[start])) {
16817 if (procs.size() <= 0) {
16821 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16827 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16828 PrintWriter pw, String[] args) {
16829 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16830 if (procs == null) {
16831 pw.println("No process found for: " + args[0]);
16835 long uptime = SystemClock.uptimeMillis();
16836 long realtime = SystemClock.elapsedRealtime();
16837 pw.println("Applications Graphics Acceleration Info:");
16838 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16840 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16841 ProcessRecord r = procs.get(i);
16842 if (r.thread != null) {
16843 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16846 TransferPipe tp = new TransferPipe();
16848 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16853 } catch (IOException e) {
16854 pw.println("Failure while dumping the app: " + r);
16856 } catch (RemoteException e) {
16857 pw.println("Got a RemoteException while dumping the app " + r);
16864 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16865 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16866 if (procs == null) {
16867 pw.println("No process found for: " + args[0]);
16871 pw.println("Applications Database Info:");
16873 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16874 ProcessRecord r = procs.get(i);
16875 if (r.thread != null) {
16876 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16879 TransferPipe tp = new TransferPipe();
16881 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16886 } catch (IOException e) {
16887 pw.println("Failure while dumping the app: " + r);
16889 } catch (RemoteException e) {
16890 pw.println("Got a RemoteException while dumping the app " + r);
16897 final static class MemItem {
16898 final boolean isProc;
16899 final String label;
16900 final String shortLabel;
16902 final long swapPss;
16904 final boolean hasActivities;
16905 ArrayList<MemItem> subitems;
16907 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16908 boolean _hasActivities) {
16911 shortLabel = _shortLabel;
16913 swapPss = _swapPss;
16915 hasActivities = _hasActivities;
16918 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16921 shortLabel = _shortLabel;
16923 swapPss = _swapPss;
16925 hasActivities = false;
16929 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16930 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16931 if (sort && !isCompact) {
16932 Collections.sort(items, new Comparator<MemItem>() {
16934 public int compare(MemItem lhs, MemItem rhs) {
16935 if (lhs.pss < rhs.pss) {
16937 } else if (lhs.pss > rhs.pss) {
16945 for (int i=0; i<items.size(); i++) {
16946 MemItem mi = items.get(i);
16949 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16950 mi.label, stringifyKBSize(mi.swapPss));
16952 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16954 } else if (mi.isProc) {
16955 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16956 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16957 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16958 pw.println(mi.hasActivities ? ",a" : ",e");
16960 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16961 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16963 if (mi.subitems != null) {
16964 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16965 true, isCompact, dumpSwapPss);
16970 // These are in KB.
16971 static final long[] DUMP_MEM_BUCKETS = new long[] {
16972 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16973 120*1024, 160*1024, 200*1024,
16974 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16975 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16978 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16979 boolean stackLike) {
16980 int start = label.lastIndexOf('.');
16981 if (start >= 0) start++;
16983 int end = label.length();
16984 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16985 if (DUMP_MEM_BUCKETS[i] >= memKB) {
16986 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16987 out.append(bucket);
16988 out.append(stackLike ? "MB." : "MB ");
16989 out.append(label, start, end);
16993 out.append(memKB/1024);
16994 out.append(stackLike ? "MB." : "MB ");
16995 out.append(label, start, end);
16998 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16999 ProcessList.NATIVE_ADJ,
17000 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17001 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17002 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17003 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17004 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17005 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17007 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17009 "System", "Persistent", "Persistent Service", "Foreground",
17010 "Visible", "Perceptible",
17011 "Heavy Weight", "Backup",
17012 "A Services", "Home",
17013 "Previous", "B Services", "Cached"
17015 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17017 "sys", "pers", "persvc", "fore",
17020 "servicea", "home",
17021 "prev", "serviceb", "cached"
17024 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17025 long realtime, boolean isCheckinRequest, boolean isCompact) {
17027 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17029 if (isCheckinRequest || isCompact) {
17030 // short checkin version
17031 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17033 pw.println("Applications Memory Usage (in Kilobytes):");
17034 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17038 private static final int KSM_SHARED = 0;
17039 private static final int KSM_SHARING = 1;
17040 private static final int KSM_UNSHARED = 2;
17041 private static final int KSM_VOLATILE = 3;
17043 private final long[] getKsmInfo() {
17044 long[] longOut = new long[4];
17045 final int[] SINGLE_LONG_FORMAT = new int[] {
17046 PROC_SPACE_TERM| PROC_OUT_LONG
17048 long[] longTmp = new long[1];
17049 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17050 SINGLE_LONG_FORMAT, null, longTmp, null);
17051 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17053 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17054 SINGLE_LONG_FORMAT, null, longTmp, null);
17055 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17057 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17058 SINGLE_LONG_FORMAT, null, longTmp, null);
17059 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17061 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17062 SINGLE_LONG_FORMAT, null, longTmp, null);
17063 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17067 private static String stringifySize(long size, int order) {
17068 Locale locale = Locale.US;
17071 return String.format(locale, "%,13d", size);
17073 return String.format(locale, "%,9dK", size / 1024);
17075 return String.format(locale, "%,5dM", size / 1024 / 1024);
17076 case 1024 * 1024 * 1024:
17077 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17079 throw new IllegalArgumentException("Invalid size order");
17083 private static String stringifyKBSize(long size) {
17084 return stringifySize(size * 1024, 1024);
17087 // Update this version number in case you change the 'compact' format
17088 private static final int MEMINFO_COMPACT_VERSION = 1;
17090 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17091 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17092 boolean dumpDetails = false;
17093 boolean dumpFullDetails = false;
17094 boolean dumpDalvik = false;
17095 boolean dumpSummaryOnly = false;
17096 boolean dumpUnreachable = false;
17097 boolean oomOnly = false;
17098 boolean isCompact = false;
17099 boolean localOnly = false;
17100 boolean packages = false;
17101 boolean isCheckinRequest = false;
17102 boolean dumpSwapPss = false;
17105 while (opti < args.length) {
17106 String opt = args[opti];
17107 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17111 if ("-a".equals(opt)) {
17112 dumpDetails = true;
17113 dumpFullDetails = true;
17115 dumpSwapPss = true;
17116 } else if ("-d".equals(opt)) {
17118 } else if ("-c".equals(opt)) {
17120 } else if ("-s".equals(opt)) {
17121 dumpDetails = true;
17122 dumpSummaryOnly = true;
17123 } else if ("-S".equals(opt)) {
17124 dumpSwapPss = true;
17125 } else if ("--unreachable".equals(opt)) {
17126 dumpUnreachable = true;
17127 } else if ("--oom".equals(opt)) {
17129 } else if ("--local".equals(opt)) {
17131 } else if ("--package".equals(opt)) {
17133 } else if ("--checkin".equals(opt)) {
17134 isCheckinRequest = true;
17136 } else if ("-h".equals(opt)) {
17137 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17138 pw.println(" -a: include all available information for each process.");
17139 pw.println(" -d: include dalvik details.");
17140 pw.println(" -c: dump in a compact machine-parseable representation.");
17141 pw.println(" -s: dump only summary of application memory usage.");
17142 pw.println(" -S: dump also SwapPss.");
17143 pw.println(" --oom: only show processes organized by oom adj.");
17144 pw.println(" --local: only collect details locally, don't call process.");
17145 pw.println(" --package: interpret process arg as package, dumping all");
17146 pw.println(" processes that have loaded that package.");
17147 pw.println(" --checkin: dump data for a checkin");
17148 pw.println("If [process] is specified it can be the name or ");
17149 pw.println("pid of a specific process to dump.");
17152 pw.println("Unknown argument: " + opt + "; use -h for help");
17156 long uptime = SystemClock.uptimeMillis();
17157 long realtime = SystemClock.elapsedRealtime();
17158 final long[] tmpLong = new long[1];
17160 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17161 if (procs == null) {
17162 // No Java processes. Maybe they want to print a native process.
17163 if (args != null && args.length > opti
17164 && args[opti].charAt(0) != '-') {
17165 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17166 = new ArrayList<ProcessCpuTracker.Stats>();
17167 updateCpuStatsNow();
17170 findPid = Integer.parseInt(args[opti]);
17171 } catch (NumberFormatException e) {
17173 synchronized (mProcessCpuTracker) {
17174 final int N = mProcessCpuTracker.countStats();
17175 for (int i=0; i<N; i++) {
17176 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17177 if (st.pid == findPid || (st.baseName != null
17178 && st.baseName.equals(args[opti]))) {
17179 nativeProcs.add(st);
17183 if (nativeProcs.size() > 0) {
17184 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17186 Debug.MemoryInfo mi = null;
17187 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17188 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17189 final int pid = r.pid;
17190 if (!isCheckinRequest && dumpDetails) {
17191 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17194 mi = new Debug.MemoryInfo();
17196 if (dumpDetails || (!brief && !oomOnly)) {
17197 Debug.getMemoryInfo(pid, mi);
17199 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17200 mi.dalvikPrivateDirty = (int)tmpLong[0];
17202 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17203 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17204 if (isCheckinRequest) {
17211 pw.println("No process found for: " + args[opti]);
17215 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17216 dumpDetails = true;
17219 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17221 String[] innerArgs = new String[args.length-opti];
17222 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17224 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17225 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17226 long nativePss = 0;
17227 long nativeSwapPss = 0;
17228 long dalvikPss = 0;
17229 long dalvikSwapPss = 0;
17230 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17232 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17235 long otherSwapPss = 0;
17236 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17237 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17239 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17240 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17241 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17242 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17245 long totalSwapPss = 0;
17246 long cachedPss = 0;
17247 long cachedSwapPss = 0;
17248 boolean hasSwapPss = false;
17250 Debug.MemoryInfo mi = null;
17251 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17252 final ProcessRecord r = procs.get(i);
17253 final IApplicationThread thread;
17256 final boolean hasActivities;
17257 synchronized (this) {
17260 oomAdj = r.getSetAdjWithServices();
17261 hasActivities = r.activities.size() > 0;
17263 if (thread != null) {
17264 if (!isCheckinRequest && dumpDetails) {
17265 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17268 mi = new Debug.MemoryInfo();
17270 if (dumpDetails || (!brief && !oomOnly)) {
17271 Debug.getMemoryInfo(pid, mi);
17272 hasSwapPss = mi.hasSwappedOutPss;
17274 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17275 mi.dalvikPrivateDirty = (int)tmpLong[0];
17279 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17280 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17281 if (isCheckinRequest) {
17287 TransferPipe tp = new TransferPipe();
17289 thread.dumpMemInfo(tp.getWriteFd(),
17290 mi, isCheckinRequest, dumpFullDetails,
17291 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17296 } catch (IOException e) {
17297 if (!isCheckinRequest) {
17298 pw.println("Got IoException! " + e);
17301 } catch (RemoteException e) {
17302 if (!isCheckinRequest) {
17303 pw.println("Got RemoteException! " + e);
17310 final long myTotalPss = mi.getTotalPss();
17311 final long myTotalUss = mi.getTotalUss();
17312 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17314 synchronized (this) {
17315 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17316 // Record this for posterity if the process has been stable.
17317 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17321 if (!isCheckinRequest && mi != null) {
17322 totalPss += myTotalPss;
17323 totalSwapPss += myTotalSwapPss;
17324 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17325 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17326 myTotalSwapPss, pid, hasActivities);
17327 procMems.add(pssItem);
17328 procMemsMap.put(pid, pssItem);
17330 nativePss += mi.nativePss;
17331 nativeSwapPss += mi.nativeSwappedOutPss;
17332 dalvikPss += mi.dalvikPss;
17333 dalvikSwapPss += mi.dalvikSwappedOutPss;
17334 for (int j=0; j<dalvikSubitemPss.length; j++) {
17335 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17336 dalvikSubitemSwapPss[j] +=
17337 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17339 otherPss += mi.otherPss;
17340 otherSwapPss += mi.otherSwappedOutPss;
17341 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17342 long mem = mi.getOtherPss(j);
17345 mem = mi.getOtherSwappedOutPss(j);
17346 miscSwapPss[j] += mem;
17347 otherSwapPss -= mem;
17350 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17351 cachedPss += myTotalPss;
17352 cachedSwapPss += myTotalSwapPss;
17355 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17356 if (oomIndex == (oomPss.length - 1)
17357 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17358 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17359 oomPss[oomIndex] += myTotalPss;
17360 oomSwapPss[oomIndex] += myTotalSwapPss;
17361 if (oomProcs[oomIndex] == null) {
17362 oomProcs[oomIndex] = new ArrayList<MemItem>();
17364 oomProcs[oomIndex].add(pssItem);
17372 long nativeProcTotalPss = 0;
17374 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17375 // If we are showing aggregations, also look for native processes to
17376 // include so that our aggregations are more accurate.
17377 updateCpuStatsNow();
17379 synchronized (mProcessCpuTracker) {
17380 final int N = mProcessCpuTracker.countStats();
17381 for (int i=0; i<N; i++) {
17382 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17383 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17385 mi = new Debug.MemoryInfo();
17387 if (!brief && !oomOnly) {
17388 Debug.getMemoryInfo(st.pid, mi);
17390 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17391 mi.nativePrivateDirty = (int)tmpLong[0];
17394 final long myTotalPss = mi.getTotalPss();
17395 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17396 totalPss += myTotalPss;
17397 nativeProcTotalPss += myTotalPss;
17399 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17400 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17401 procMems.add(pssItem);
17403 nativePss += mi.nativePss;
17404 nativeSwapPss += mi.nativeSwappedOutPss;
17405 dalvikPss += mi.dalvikPss;
17406 dalvikSwapPss += mi.dalvikSwappedOutPss;
17407 for (int j=0; j<dalvikSubitemPss.length; j++) {
17408 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17409 dalvikSubitemSwapPss[j] +=
17410 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17412 otherPss += mi.otherPss;
17413 otherSwapPss += mi.otherSwappedOutPss;
17414 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17415 long mem = mi.getOtherPss(j);
17418 mem = mi.getOtherSwappedOutPss(j);
17419 miscSwapPss[j] += mem;
17420 otherSwapPss -= mem;
17422 oomPss[0] += myTotalPss;
17423 oomSwapPss[0] += myTotalSwapPss;
17424 if (oomProcs[0] == null) {
17425 oomProcs[0] = new ArrayList<MemItem>();
17427 oomProcs[0].add(pssItem);
17432 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17434 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17435 final int dalvikId = -2;
17436 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17437 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17438 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17439 String label = Debug.MemoryInfo.getOtherLabel(j);
17440 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17442 if (dalvikSubitemPss.length > 0) {
17443 // Add dalvik subitems.
17444 for (MemItem memItem : catMems) {
17445 int memItemStart = 0, memItemEnd = 0;
17446 if (memItem.id == dalvikId) {
17447 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17448 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17449 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17450 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17451 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17452 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17453 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17454 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17455 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17456 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17457 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17459 continue; // No subitems, continue.
17461 memItem.subitems = new ArrayList<MemItem>();
17462 for (int j=memItemStart; j<=memItemEnd; j++) {
17463 final String name = Debug.MemoryInfo.getOtherLabel(
17464 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17465 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17466 dalvikSubitemSwapPss[j], j));
17471 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17472 for (int j=0; j<oomPss.length; j++) {
17473 if (oomPss[j] != 0) {
17474 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17475 : DUMP_MEM_OOM_LABEL[j];
17476 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17477 DUMP_MEM_OOM_ADJ[j]);
17478 item.subitems = oomProcs[j];
17483 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17484 if (!brief && !oomOnly && !isCompact) {
17486 pw.println("Total PSS by process:");
17487 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17491 pw.println("Total PSS by OOM adjustment:");
17493 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17494 if (!brief && !oomOnly) {
17495 PrintWriter out = categoryPw != null ? categoryPw : pw;
17498 out.println("Total PSS by category:");
17500 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17505 MemInfoReader memInfo = new MemInfoReader();
17506 memInfo.readMemInfo();
17507 if (nativeProcTotalPss > 0) {
17508 synchronized (this) {
17509 final long cachedKb = memInfo.getCachedSizeKb();
17510 final long freeKb = memInfo.getFreeSizeKb();
17511 final long zramKb = memInfo.getZramTotalSizeKb();
17512 final long kernelKb = memInfo.getKernelUsedSizeKb();
17513 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17514 kernelKb*1024, nativeProcTotalPss*1024);
17515 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17516 nativeProcTotalPss);
17521 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17522 pw.print(" (status ");
17523 switch (mLastMemoryLevel) {
17524 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17525 pw.println("normal)");
17527 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17528 pw.println("moderate)");
17530 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17531 pw.println("low)");
17533 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17534 pw.println("critical)");
17537 pw.print(mLastMemoryLevel);
17541 pw.print(" Free RAM: ");
17542 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17543 + memInfo.getFreeSizeKb()));
17545 pw.print(stringifyKBSize(cachedPss));
17546 pw.print(" cached pss + ");
17547 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17548 pw.print(" cached kernel + ");
17549 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17550 pw.println(" free)");
17552 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17553 pw.print(cachedPss + memInfo.getCachedSizeKb()
17554 + memInfo.getFreeSizeKb()); pw.print(",");
17555 pw.println(totalPss - cachedPss);
17558 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17559 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17560 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17562 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17563 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17564 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17565 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17566 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17568 pw.print("lostram,"); pw.println(lostRAM);
17571 if (memInfo.getZramTotalSizeKb() != 0) {
17573 pw.print(" ZRAM: ");
17574 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17575 pw.print(" physical used for ");
17576 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17577 - memInfo.getSwapFreeSizeKb()));
17578 pw.print(" in swap (");
17579 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17580 pw.println(" total swap)");
17582 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17583 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17584 pw.println(memInfo.getSwapFreeSizeKb());
17587 final long[] ksm = getKsmInfo();
17589 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17590 || ksm[KSM_VOLATILE] != 0) {
17591 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17592 pw.print(" saved from shared ");
17593 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17594 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17595 pw.print(" unshared; ");
17596 pw.print(stringifyKBSize(
17597 ksm[KSM_VOLATILE])); pw.println(" volatile");
17599 pw.print(" Tuning: ");
17600 pw.print(ActivityManager.staticGetMemoryClass());
17601 pw.print(" (large ");
17602 pw.print(ActivityManager.staticGetLargeMemoryClass());
17603 pw.print("), oom ");
17604 pw.print(stringifySize(
17605 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17606 pw.print(", restore limit ");
17607 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17608 if (ActivityManager.isLowRamDeviceStatic()) {
17609 pw.print(" (low-ram)");
17611 if (ActivityManager.isHighEndGfx()) {
17612 pw.print(" (high-end-gfx)");
17616 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17617 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17618 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17619 pw.print("tuning,");
17620 pw.print(ActivityManager.staticGetMemoryClass());
17622 pw.print(ActivityManager.staticGetLargeMemoryClass());
17624 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17625 if (ActivityManager.isLowRamDeviceStatic()) {
17626 pw.print(",low-ram");
17628 if (ActivityManager.isHighEndGfx()) {
17629 pw.print(",high-end-gfx");
17637 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17638 long memtrack, String name) {
17640 sb.append(ProcessList.makeOomAdjString(oomAdj));
17642 sb.append(ProcessList.makeProcStateString(procState));
17644 ProcessList.appendRamKb(sb, pss);
17647 if (memtrack > 0) {
17649 sb.append(stringifyKBSize(memtrack));
17650 sb.append(" memtrack)");
17654 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17655 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17656 sb.append(" (pid ");
17659 sb.append(mi.adjType);
17661 if (mi.adjReason != null) {
17663 sb.append(mi.adjReason);
17668 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17669 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17670 for (int i=0, N=memInfos.size(); i<N; i++) {
17671 ProcessMemInfo mi = memInfos.get(i);
17672 infoMap.put(mi.pid, mi);
17674 updateCpuStatsNow();
17675 long[] memtrackTmp = new long[1];
17676 final List<ProcessCpuTracker.Stats> stats;
17677 // Get a list of Stats that have vsize > 0
17678 synchronized (mProcessCpuTracker) {
17679 stats = mProcessCpuTracker.getStats((st) -> {
17680 return st.vsize > 0;
17683 final int statsCount = stats.size();
17684 for (int i = 0; i < statsCount; i++) {
17685 ProcessCpuTracker.Stats st = stats.get(i);
17686 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17688 if (infoMap.indexOfKey(st.pid) < 0) {
17689 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17690 ProcessList.NATIVE_ADJ, -1, "native", null);
17692 mi.memtrack = memtrackTmp[0];
17699 long totalMemtrack = 0;
17700 for (int i=0, N=memInfos.size(); i<N; i++) {
17701 ProcessMemInfo mi = memInfos.get(i);
17703 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17704 mi.memtrack = memtrackTmp[0];
17706 totalPss += mi.pss;
17707 totalMemtrack += mi.memtrack;
17709 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17710 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17711 if (lhs.oomAdj != rhs.oomAdj) {
17712 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17714 if (lhs.pss != rhs.pss) {
17715 return lhs.pss < rhs.pss ? 1 : -1;
17721 StringBuilder tag = new StringBuilder(128);
17722 StringBuilder stack = new StringBuilder(128);
17723 tag.append("Low on memory -- ");
17724 appendMemBucket(tag, totalPss, "total", false);
17725 appendMemBucket(stack, totalPss, "total", true);
17727 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17728 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17729 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17731 boolean firstLine = true;
17732 int lastOomAdj = Integer.MIN_VALUE;
17733 long extraNativeRam = 0;
17734 long extraNativeMemtrack = 0;
17735 long cachedPss = 0;
17736 for (int i=0, N=memInfos.size(); i<N; i++) {
17737 ProcessMemInfo mi = memInfos.get(i);
17739 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17740 cachedPss += mi.pss;
17743 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17744 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17745 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17746 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17747 if (lastOomAdj != mi.oomAdj) {
17748 lastOomAdj = mi.oomAdj;
17749 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17752 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17757 stack.append("\n\t at ");
17765 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17766 appendMemBucket(tag, mi.pss, mi.name, false);
17768 appendMemBucket(stack, mi.pss, mi.name, true);
17769 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17770 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17772 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17773 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17774 stack.append(DUMP_MEM_OOM_LABEL[k]);
17776 stack.append(DUMP_MEM_OOM_ADJ[k]);
17783 appendMemInfo(fullNativeBuilder, mi);
17784 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17785 // The short form only has native processes that are >= 512K.
17786 if (mi.pss >= 512) {
17787 appendMemInfo(shortNativeBuilder, mi);
17789 extraNativeRam += mi.pss;
17790 extraNativeMemtrack += mi.memtrack;
17793 // Short form has all other details, but if we have collected RAM
17794 // from smaller native processes let's dump a summary of that.
17795 if (extraNativeRam > 0) {
17796 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17797 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17798 shortNativeBuilder.append('\n');
17799 extraNativeRam = 0;
17801 appendMemInfo(fullJavaBuilder, mi);
17805 fullJavaBuilder.append(" ");
17806 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17807 fullJavaBuilder.append(": TOTAL");
17808 if (totalMemtrack > 0) {
17809 fullJavaBuilder.append(" (");
17810 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17811 fullJavaBuilder.append(" memtrack)");
17814 fullJavaBuilder.append("\n");
17816 MemInfoReader memInfo = new MemInfoReader();
17817 memInfo.readMemInfo();
17818 final long[] infos = memInfo.getRawInfo();
17820 StringBuilder memInfoBuilder = new StringBuilder(1024);
17821 Debug.getMemInfo(infos);
17822 memInfoBuilder.append(" MemInfo: ");
17823 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17824 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17825 memInfoBuilder.append(stringifyKBSize(
17826 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17827 memInfoBuilder.append(stringifyKBSize(
17828 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17829 memInfoBuilder.append(stringifyKBSize(
17830 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17831 memInfoBuilder.append(" ");
17832 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17833 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17834 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17835 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17836 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17837 memInfoBuilder.append(" ZRAM: ");
17838 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17839 memInfoBuilder.append(" RAM, ");
17840 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17841 memInfoBuilder.append(" swap total, ");
17842 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17843 memInfoBuilder.append(" swap free\n");
17845 final long[] ksm = getKsmInfo();
17846 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17847 || ksm[KSM_VOLATILE] != 0) {
17848 memInfoBuilder.append(" KSM: ");
17849 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17850 memInfoBuilder.append(" saved from shared ");
17851 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17852 memInfoBuilder.append("\n ");
17853 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17854 memInfoBuilder.append(" unshared; ");
17855 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17856 memInfoBuilder.append(" volatile\n");
17858 memInfoBuilder.append(" Free RAM: ");
17859 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17860 + memInfo.getFreeSizeKb()));
17861 memInfoBuilder.append("\n");
17862 memInfoBuilder.append(" Used RAM: ");
17863 memInfoBuilder.append(stringifyKBSize(
17864 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17865 memInfoBuilder.append("\n");
17866 memInfoBuilder.append(" Lost RAM: ");
17867 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17868 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17869 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17870 memInfoBuilder.append("\n");
17871 Slog.i(TAG, "Low on memory:");
17872 Slog.i(TAG, shortNativeBuilder.toString());
17873 Slog.i(TAG, fullJavaBuilder.toString());
17874 Slog.i(TAG, memInfoBuilder.toString());
17876 StringBuilder dropBuilder = new StringBuilder(1024);
17878 StringWriter oomSw = new StringWriter();
17879 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17880 StringWriter catSw = new StringWriter();
17881 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17882 String[] emptyArgs = new String[] { };
17883 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17885 String oomString = oomSw.toString();
17887 dropBuilder.append("Low on memory:");
17888 dropBuilder.append(stack);
17889 dropBuilder.append('\n');
17890 dropBuilder.append(fullNativeBuilder);
17891 dropBuilder.append(fullJavaBuilder);
17892 dropBuilder.append('\n');
17893 dropBuilder.append(memInfoBuilder);
17894 dropBuilder.append('\n');
17896 dropBuilder.append(oomString);
17897 dropBuilder.append('\n');
17899 StringWriter catSw = new StringWriter();
17900 synchronized (ActivityManagerService.this) {
17901 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17902 String[] emptyArgs = new String[] { };
17904 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17906 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17907 false, null).dumpLocked();
17909 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17912 dropBuilder.append(catSw.toString());
17913 addErrorToDropBox("lowmem", null, "system_server", null,
17914 null, tag.toString(), dropBuilder.toString(), null, null);
17915 //Slog.i(TAG, "Sent to dropbox:");
17916 //Slog.i(TAG, dropBuilder.toString());
17917 synchronized (ActivityManagerService.this) {
17918 long now = SystemClock.uptimeMillis();
17919 if (mLastMemUsageReportTime < now) {
17920 mLastMemUsageReportTime = now;
17926 * Searches array of arguments for the specified string
17927 * @param args array of argument strings
17928 * @param value value to search for
17929 * @return true if the value is contained in the array
17931 private static boolean scanArgs(String[] args, String value) {
17932 if (args != null) {
17933 for (String arg : args) {
17934 if (value.equals(arg)) {
17942 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17943 ContentProviderRecord cpr, boolean always) {
17944 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17946 if (!inLaunching || always) {
17947 synchronized (cpr) {
17948 cpr.launchingApp = null;
17951 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17952 String names[] = cpr.info.authority.split(";");
17953 for (int j = 0; j < names.length; j++) {
17954 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17958 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17959 ContentProviderConnection conn = cpr.connections.get(i);
17960 if (conn.waiting) {
17961 // If this connection is waiting for the provider, then we don't
17962 // need to mess with its process unless we are always removing
17963 // or for some reason the provider is not currently launching.
17964 if (inLaunching && !always) {
17968 ProcessRecord capp = conn.client;
17970 if (conn.stableCount > 0) {
17971 if (!capp.persistent && capp.thread != null
17973 && capp.pid != MY_PID) {
17974 capp.kill("depends on provider "
17975 + cpr.name.flattenToShortString()
17976 + " in dying proc " + (proc != null ? proc.processName : "??")
17977 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17979 } else if (capp.thread != null && conn.provider.provider != null) {
17981 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17982 } catch (RemoteException e) {
17984 // In the protocol here, we don't expect the client to correctly
17985 // clean up this connection, we'll just remove it.
17986 cpr.connections.remove(i);
17987 if (conn.client.conProviders.remove(conn)) {
17988 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17993 if (inLaunching && always) {
17994 mLaunchingProviders.remove(cpr);
17996 return inLaunching;
18000 * Main code for cleaning up a process when it has gone away. This is
18001 * called both as a result of the process dying, or directly when stopping
18002 * a process when running in single process mode.
18004 * @return Returns true if the given process has been restarted, so the
18005 * app that was passed in must remain on the process lists.
18007 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18008 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18010 removeLruProcessLocked(app);
18011 ProcessList.remove(app.pid);
18014 mProcessesToGc.remove(app);
18015 mPendingPssProcesses.remove(app);
18017 // Dismiss any open dialogs.
18018 if (app.crashDialog != null && !app.forceCrashReport) {
18019 app.crashDialog.dismiss();
18020 app.crashDialog = null;
18022 if (app.anrDialog != null) {
18023 app.anrDialog.dismiss();
18024 app.anrDialog = null;
18026 if (app.waitDialog != null) {
18027 app.waitDialog.dismiss();
18028 app.waitDialog = null;
18031 app.crashing = false;
18032 app.notResponding = false;
18034 app.resetPackageList(mProcessStats);
18035 app.unlinkDeathRecipient();
18036 app.makeInactive(mProcessStats);
18037 app.waitingToKill = null;
18038 app.forcingToImportant = null;
18039 updateProcessForegroundLocked(app, false, false);
18040 app.foregroundActivities = false;
18041 app.hasShownUi = false;
18042 app.treatLikeActivity = false;
18043 app.hasAboveClient = false;
18044 app.hasClientActivities = false;
18046 mServices.killServicesLocked(app, allowRestart);
18048 boolean restart = false;
18050 // Remove published content providers.
18051 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18052 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18053 final boolean always = app.bad || !allowRestart;
18054 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18055 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18056 // We left the provider in the launching list, need to
18061 cpr.provider = null;
18064 app.pubProviders.clear();
18066 // Take care of any launching providers waiting for this process.
18067 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18071 // Unregister from connected content providers.
18072 if (!app.conProviders.isEmpty()) {
18073 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18074 ContentProviderConnection conn = app.conProviders.get(i);
18075 conn.provider.connections.remove(conn);
18076 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18077 conn.provider.name);
18079 app.conProviders.clear();
18082 // At this point there may be remaining entries in mLaunchingProviders
18083 // where we were the only one waiting, so they are no longer of use.
18084 // Look for these and clean up if found.
18085 // XXX Commented out for now. Trying to figure out a way to reproduce
18086 // the actual situation to identify what is actually going on.
18088 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18089 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18090 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18091 synchronized (cpr) {
18092 cpr.launchingApp = null;
18099 skipCurrentReceiverLocked(app);
18101 // Unregister any receivers.
18102 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18103 removeReceiverLocked(app.receivers.valueAt(i));
18105 app.receivers.clear();
18107 // If the app is undergoing backup, tell the backup manager about it
18108 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18109 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18110 + mBackupTarget.appInfo + " died during backup");
18111 mHandler.post(new Runnable() {
18115 IBackupManager bm = IBackupManager.Stub.asInterface(
18116 ServiceManager.getService(Context.BACKUP_SERVICE));
18117 bm.agentDisconnected(app.info.packageName);
18118 } catch (RemoteException e) {
18119 // can't happen; backup manager is local
18125 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18126 ProcessChangeItem item = mPendingProcessChanges.get(i);
18127 if (item.pid == app.pid) {
18128 mPendingProcessChanges.remove(i);
18129 mAvailProcessChanges.add(item);
18132 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18133 null).sendToTarget();
18135 // If the caller is restarting this app, then leave it in its
18136 // current lists and let the caller take care of it.
18141 if (!app.persistent || app.isolated) {
18142 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18143 "Removing non-persistent process during cleanup: " + app);
18144 if (!replacingPid) {
18145 removeProcessNameLocked(app.processName, app.uid, app);
18147 if (mHeavyWeightProcess == app) {
18148 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18149 mHeavyWeightProcess.userId, 0));
18150 mHeavyWeightProcess = null;
18152 } else if (!app.removed) {
18153 // This app is persistent, so we need to keep its record around.
18154 // If it is not already on the pending app list, add it there
18155 // and start a new process for it.
18156 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18157 mPersistentStartingProcesses.add(app);
18161 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18162 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18163 mProcessesOnHold.remove(app);
18165 if (app == mHomeProcess) {
18166 mHomeProcess = null;
18168 if (app == mPreviousProcess) {
18169 mPreviousProcess = null;
18172 if (restart && !app.isolated) {
18173 // We have components that still need to be running in the
18174 // process, so re-launch it.
18176 ProcessList.remove(app.pid);
18178 addProcessNameLocked(app);
18179 startProcessLocked(app, "restart", app.processName);
18181 } else if (app.pid > 0 && app.pid != MY_PID) {
18184 synchronized (mPidsSelfLocked) {
18185 mPidsSelfLocked.remove(app.pid);
18186 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18188 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18189 if (app.isolated) {
18190 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18197 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18198 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18199 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18200 if (cpr.launchingApp == app) {
18207 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18208 // Look through the content providers we are waiting to have launched,
18209 // and if any run in this process then either schedule a restart of
18210 // the process or kill the client waiting for it if this process has
18212 boolean restart = false;
18213 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18214 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18215 if (cpr.launchingApp == app) {
18216 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18219 removeDyingProviderLocked(app, cpr, true);
18226 // =========================================================
18228 // =========================================================
18231 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18233 enforceNotIsolatedCaller("getServices");
18235 final int callingUid = Binder.getCallingUid();
18236 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18237 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18238 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18240 synchronized (this) {
18241 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18242 allowed, canInteractAcrossUsers);
18247 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18248 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18249 synchronized (this) {
18250 return mServices.getRunningServiceControlPanelLocked(name);
18255 public ComponentName startService(IApplicationThread caller, Intent service,
18256 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18257 throws TransactionTooLargeException {
18258 enforceNotIsolatedCaller("startService");
18259 // Refuse possible leaked file descriptors
18260 if (service != null && service.hasFileDescriptors() == true) {
18261 throw new IllegalArgumentException("File descriptors passed in Intent");
18264 if (callingPackage == null) {
18265 throw new IllegalArgumentException("callingPackage cannot be null");
18268 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18269 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18270 synchronized(this) {
18271 final int callingPid = Binder.getCallingPid();
18272 final int callingUid = Binder.getCallingUid();
18273 final long origId = Binder.clearCallingIdentity();
18276 res = mServices.startServiceLocked(caller, service,
18277 resolvedType, callingPid, callingUid,
18278 requireForeground, callingPackage, userId);
18280 Binder.restoreCallingIdentity(origId);
18286 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18287 boolean fgRequired, String callingPackage, int userId)
18288 throws TransactionTooLargeException {
18289 synchronized(this) {
18290 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18291 "startServiceInPackage: " + service + " type=" + resolvedType);
18292 final long origId = Binder.clearCallingIdentity();
18295 res = mServices.startServiceLocked(null, service,
18296 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18298 Binder.restoreCallingIdentity(origId);
18305 public int stopService(IApplicationThread caller, Intent service,
18306 String resolvedType, int userId) {
18307 enforceNotIsolatedCaller("stopService");
18308 // Refuse possible leaked file descriptors
18309 if (service != null && service.hasFileDescriptors() == true) {
18310 throw new IllegalArgumentException("File descriptors passed in Intent");
18313 synchronized(this) {
18314 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18319 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18320 enforceNotIsolatedCaller("peekService");
18321 // Refuse possible leaked file descriptors
18322 if (service != null && service.hasFileDescriptors() == true) {
18323 throw new IllegalArgumentException("File descriptors passed in Intent");
18326 if (callingPackage == null) {
18327 throw new IllegalArgumentException("callingPackage cannot be null");
18330 synchronized(this) {
18331 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18336 public boolean stopServiceToken(ComponentName className, IBinder token,
18338 synchronized(this) {
18339 return mServices.stopServiceTokenLocked(className, token, startId);
18344 public void setServiceForeground(ComponentName className, IBinder token,
18345 int id, Notification notification, int flags) {
18346 synchronized(this) {
18347 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18352 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18353 boolean requireFull, String name, String callerPackage) {
18354 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18355 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18358 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18359 String className, int flags) {
18360 boolean result = false;
18361 // For apps that don't have pre-defined UIDs, check for permission
18362 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18363 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18364 if (ActivityManager.checkUidPermission(
18365 INTERACT_ACROSS_USERS,
18366 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18367 ComponentName comp = new ComponentName(aInfo.packageName, className);
18368 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18369 + " requests FLAG_SINGLE_USER, but app does not hold "
18370 + INTERACT_ACROSS_USERS;
18372 throw new SecurityException(msg);
18374 // Permission passed
18377 } else if ("system".equals(componentProcessName)) {
18379 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18380 // Phone app and persistent apps are allowed to export singleuser providers.
18381 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18382 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18384 if (DEBUG_MU) Slog.v(TAG_MU,
18385 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18386 + Integer.toHexString(flags) + ") = " + result);
18391 * Checks to see if the caller is in the same app as the singleton
18392 * component, or the component is in a special app. It allows special apps
18393 * to export singleton components but prevents exporting singleton
18394 * components for regular apps.
18396 boolean isValidSingletonCall(int callingUid, int componentUid) {
18397 int componentAppId = UserHandle.getAppId(componentUid);
18398 return UserHandle.isSameApp(callingUid, componentUid)
18399 || componentAppId == SYSTEM_UID
18400 || componentAppId == PHONE_UID
18401 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18402 == PackageManager.PERMISSION_GRANTED;
18405 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18406 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18407 int userId) throws TransactionTooLargeException {
18408 enforceNotIsolatedCaller("bindService");
18410 // Refuse possible leaked file descriptors
18411 if (service != null && service.hasFileDescriptors() == true) {
18412 throw new IllegalArgumentException("File descriptors passed in Intent");
18415 if (callingPackage == null) {
18416 throw new IllegalArgumentException("callingPackage cannot be null");
18419 synchronized(this) {
18420 return mServices.bindServiceLocked(caller, token, service,
18421 resolvedType, connection, flags, callingPackage, userId);
18425 public boolean unbindService(IServiceConnection connection) {
18426 synchronized (this) {
18427 return mServices.unbindServiceLocked(connection);
18431 public void publishService(IBinder token, Intent intent, IBinder service) {
18432 // Refuse possible leaked file descriptors
18433 if (intent != null && intent.hasFileDescriptors() == true) {
18434 throw new IllegalArgumentException("File descriptors passed in Intent");
18437 synchronized(this) {
18438 if (!(token instanceof ServiceRecord)) {
18439 throw new IllegalArgumentException("Invalid service token");
18441 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18445 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18446 // Refuse possible leaked file descriptors
18447 if (intent != null && intent.hasFileDescriptors() == true) {
18448 throw new IllegalArgumentException("File descriptors passed in Intent");
18451 synchronized(this) {
18452 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18456 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18457 synchronized(this) {
18458 if (!(token instanceof ServiceRecord)) {
18459 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18460 throw new IllegalArgumentException("Invalid service token");
18462 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18466 // =========================================================
18467 // BACKUP AND RESTORE
18468 // =========================================================
18470 // Cause the target app to be launched if necessary and its backup agent
18471 // instantiated. The backup agent will invoke backupAgentCreated() on the
18472 // activity manager to announce its creation.
18473 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18474 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18475 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18477 IPackageManager pm = AppGlobals.getPackageManager();
18478 ApplicationInfo app = null;
18480 app = pm.getApplicationInfo(packageName, 0, userId);
18481 } catch (RemoteException e) {
18482 // can't happen; package manager is process-local
18485 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18492 synchronized(this) {
18493 // !!! TODO: currently no check here that we're already bound
18494 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18495 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18496 synchronized (stats) {
18497 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18500 // Backup agent is now in use, its package can't be stopped.
18502 AppGlobals.getPackageManager().setPackageStoppedState(
18503 app.packageName, false, UserHandle.getUserId(app.uid));
18504 } catch (RemoteException e) {
18505 } catch (IllegalArgumentException e) {
18506 Slog.w(TAG, "Failed trying to unstop package "
18507 + app.packageName + ": " + e);
18510 BackupRecord r = new BackupRecord(ss, app, backupMode);
18511 ComponentName hostingName =
18512 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18513 ? new ComponentName(app.packageName, app.backupAgentName)
18514 : new ComponentName("android", "FullBackupAgent");
18515 // startProcessLocked() returns existing proc's record if it's already running
18516 ProcessRecord proc = startProcessLocked(app.processName, app,
18517 false, 0, "backup", hostingName, false, false, false);
18518 if (proc == null) {
18519 Slog.e(TAG, "Unable to start backup agent process " + r);
18523 // If the app is a regular app (uid >= 10000) and not the system server or phone
18524 // process, etc, then mark it as being in full backup so that certain calls to the
18525 // process can be blocked. This is not reset to false anywhere because we kill the
18526 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18527 if (UserHandle.isApp(app.uid) &&
18528 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18529 proc.inFullBackup = true;
18532 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18533 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18535 mBackupAppName = app.packageName;
18537 // Try not to kill the process during backup
18538 updateOomAdjLocked(proc, true);
18540 // If the process is already attached, schedule the creation of the backup agent now.
18541 // If it is not yet live, this will be done when it attaches to the framework.
18542 if (proc.thread != null) {
18543 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18545 proc.thread.scheduleCreateBackupAgent(app,
18546 compatibilityInfoForPackageLocked(app), backupMode);
18547 } catch (RemoteException e) {
18548 // Will time out on the backup manager side
18551 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18553 // Invariants: at this point, the target app process exists and the application
18554 // is either already running or in the process of coming up. mBackupTarget and
18555 // mBackupAppName describe the app, so that when it binds back to the AM we
18556 // know that it's scheduled for a backup-agent operation.
18559 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18560 if (oldBackupUid != -1) {
18561 js.removeBackingUpUid(oldBackupUid);
18563 if (newBackupUid != -1) {
18564 js.addBackingUpUid(newBackupUid);
18571 public void clearPendingBackup() {
18572 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18573 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18575 synchronized (this) {
18576 mBackupTarget = null;
18577 mBackupAppName = null;
18580 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18581 js.clearAllBackingUpUids();
18584 // A backup agent has just come up
18585 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18586 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18589 synchronized(this) {
18590 if (!agentPackageName.equals(mBackupAppName)) {
18591 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18596 long oldIdent = Binder.clearCallingIdentity();
18598 IBackupManager bm = IBackupManager.Stub.asInterface(
18599 ServiceManager.getService(Context.BACKUP_SERVICE));
18600 bm.agentConnected(agentPackageName, agent);
18601 } catch (RemoteException e) {
18602 // can't happen; the backup manager service is local
18603 } catch (Exception e) {
18604 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18605 e.printStackTrace();
18607 Binder.restoreCallingIdentity(oldIdent);
18611 // done with this agent
18612 public void unbindBackupAgent(ApplicationInfo appInfo) {
18613 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18614 if (appInfo == null) {
18615 Slog.w(TAG, "unbind backup agent for null app");
18621 synchronized(this) {
18623 if (mBackupAppName == null) {
18624 Slog.w(TAG, "Unbinding backup agent with no active backup");
18628 if (!mBackupAppName.equals(appInfo.packageName)) {
18629 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18633 // Not backing this app up any more; reset its OOM adjustment
18634 final ProcessRecord proc = mBackupTarget.app;
18635 updateOomAdjLocked(proc, true);
18636 proc.inFullBackup = false;
18638 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18640 // If the app crashed during backup, 'thread' will be null here
18641 if (proc.thread != null) {
18643 proc.thread.scheduleDestroyBackupAgent(appInfo,
18644 compatibilityInfoForPackageLocked(appInfo));
18645 } catch (Exception e) {
18646 Slog.e(TAG, "Exception when unbinding backup agent:");
18647 e.printStackTrace();
18651 mBackupTarget = null;
18652 mBackupAppName = null;
18656 if (oldBackupUid != -1) {
18657 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18658 js.removeBackingUpUid(oldBackupUid);
18662 // =========================================================
18664 // =========================================================
18666 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18667 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18670 // Easy case -- we have the app's ProcessRecord.
18671 if (record != null) {
18672 return record.info.isInstantApp();
18674 // Otherwise check with PackageManager.
18675 if (callerPackage == null) {
18676 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18677 throw new IllegalArgumentException("Calling application did not provide package name");
18679 mAppOpsService.checkPackage(uid, callerPackage);
18681 IPackageManager pm = AppGlobals.getPackageManager();
18682 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18683 } catch (RemoteException e) {
18684 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18689 boolean isPendingBroadcastProcessLocked(int pid) {
18690 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18691 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18694 void skipPendingBroadcastLocked(int pid) {
18695 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18696 for (BroadcastQueue queue : mBroadcastQueues) {
18697 queue.skipPendingBroadcastLocked(pid);
18701 // The app just attached; send any pending broadcasts that it should receive
18702 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18703 boolean didSomething = false;
18704 for (BroadcastQueue queue : mBroadcastQueues) {
18705 didSomething |= queue.sendPendingBroadcastsLocked(app);
18707 return didSomething;
18710 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18711 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18713 enforceNotIsolatedCaller("registerReceiver");
18714 ArrayList<Intent> stickyIntents = null;
18715 ProcessRecord callerApp = null;
18716 final boolean visibleToInstantApps
18717 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18720 boolean instantApp;
18721 synchronized(this) {
18722 if (caller != null) {
18723 callerApp = getRecordForAppLocked(caller);
18724 if (callerApp == null) {
18725 throw new SecurityException(
18726 "Unable to find app for caller " + caller
18727 + " (pid=" + Binder.getCallingPid()
18728 + ") when registering receiver " + receiver);
18730 if (callerApp.info.uid != SYSTEM_UID &&
18731 !callerApp.pkgList.containsKey(callerPackage) &&
18732 !"android".equals(callerPackage)) {
18733 throw new SecurityException("Given caller package " + callerPackage
18734 + " is not running in process " + callerApp);
18736 callingUid = callerApp.info.uid;
18737 callingPid = callerApp.pid;
18739 callerPackage = null;
18740 callingUid = Binder.getCallingUid();
18741 callingPid = Binder.getCallingPid();
18744 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18745 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18746 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18748 Iterator<String> actions = filter.actionsIterator();
18749 if (actions == null) {
18750 ArrayList<String> noAction = new ArrayList<String>(1);
18751 noAction.add(null);
18752 actions = noAction.iterator();
18755 // Collect stickies of users
18756 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18757 while (actions.hasNext()) {
18758 String action = actions.next();
18759 for (int id : userIds) {
18760 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18761 if (stickies != null) {
18762 ArrayList<Intent> intents = stickies.get(action);
18763 if (intents != null) {
18764 if (stickyIntents == null) {
18765 stickyIntents = new ArrayList<Intent>();
18767 stickyIntents.addAll(intents);
18774 ArrayList<Intent> allSticky = null;
18775 if (stickyIntents != null) {
18776 final ContentResolver resolver = mContext.getContentResolver();
18777 // Look for any matching sticky broadcasts...
18778 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18779 Intent intent = stickyIntents.get(i);
18780 // Don't provided intents that aren't available to instant apps.
18782 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18785 // If intent has scheme "content", it will need to acccess
18786 // provider that needs to lock mProviderMap in ActivityThread
18787 // and also it may need to wait application response, so we
18788 // cannot lock ActivityManagerService here.
18789 if (filter.match(resolver, intent, true, TAG) >= 0) {
18790 if (allSticky == null) {
18791 allSticky = new ArrayList<Intent>();
18793 allSticky.add(intent);
18798 // The first sticky in the list is returned directly back to the client.
18799 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18800 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18801 if (receiver == null) {
18805 synchronized (this) {
18806 if (callerApp != null && (callerApp.thread == null
18807 || callerApp.thread.asBinder() != caller.asBinder())) {
18808 // Original caller already died
18811 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18813 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18815 if (rl.app != null) {
18816 rl.app.receivers.add(rl);
18819 receiver.asBinder().linkToDeath(rl, 0);
18820 } catch (RemoteException e) {
18823 rl.linkedToDeath = true;
18825 mRegisteredReceivers.put(receiver.asBinder(), rl);
18826 } else if (rl.uid != callingUid) {
18827 throw new IllegalArgumentException(
18828 "Receiver requested to register for uid " + callingUid
18829 + " was previously registered for uid " + rl.uid
18830 + " callerPackage is " + callerPackage);
18831 } else if (rl.pid != callingPid) {
18832 throw new IllegalArgumentException(
18833 "Receiver requested to register for pid " + callingPid
18834 + " was previously registered for pid " + rl.pid
18835 + " callerPackage is " + callerPackage);
18836 } else if (rl.userId != userId) {
18837 throw new IllegalArgumentException(
18838 "Receiver requested to register for user " + userId
18839 + " was previously registered for user " + rl.userId
18840 + " callerPackage is " + callerPackage);
18842 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18843 permission, callingUid, userId, instantApp, visibleToInstantApps);
18845 if (!bf.debugCheck()) {
18846 Slog.w(TAG, "==> For Dynamic broadcast");
18848 mReceiverResolver.addFilter(bf);
18850 // Enqueue broadcasts for all existing stickies that match
18852 if (allSticky != null) {
18853 ArrayList receivers = new ArrayList();
18856 final int stickyCount = allSticky.size();
18857 for (int i = 0; i < stickyCount; i++) {
18858 Intent intent = allSticky.get(i);
18859 BroadcastQueue queue = broadcastQueueForIntent(intent);
18860 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18861 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18862 null, 0, null, null, false, true, true, -1);
18863 queue.enqueueParallelBroadcastLocked(r);
18864 queue.scheduleBroadcastsLocked();
18872 public void unregisterReceiver(IIntentReceiver receiver) {
18873 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18875 final long origId = Binder.clearCallingIdentity();
18877 boolean doTrim = false;
18879 synchronized(this) {
18880 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18882 final BroadcastRecord r = rl.curBroadcast;
18883 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18884 final boolean doNext = r.queue.finishReceiverLocked(
18885 r, r.resultCode, r.resultData, r.resultExtras,
18886 r.resultAbort, false);
18889 r.queue.processNextBroadcast(false);
18893 if (rl.app != null) {
18894 rl.app.receivers.remove(rl);
18896 removeReceiverLocked(rl);
18897 if (rl.linkedToDeath) {
18898 rl.linkedToDeath = false;
18899 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18904 // If we actually concluded any broadcasts, we might now be able
18905 // to trim the recipients' apps from our working set
18907 trimApplications();
18912 Binder.restoreCallingIdentity(origId);
18916 void removeReceiverLocked(ReceiverList rl) {
18917 mRegisteredReceivers.remove(rl.receiver.asBinder());
18918 for (int i = rl.size() - 1; i >= 0; i--) {
18919 mReceiverResolver.removeFilter(rl.get(i));
18923 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18924 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18925 ProcessRecord r = mLruProcesses.get(i);
18926 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18928 r.thread.dispatchPackageBroadcast(cmd, packages);
18929 } catch (RemoteException ex) {
18935 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18936 int callingUid, int[] users) {
18937 // TODO: come back and remove this assumption to triage all broadcasts
18938 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18940 List<ResolveInfo> receivers = null;
18942 HashSet<ComponentName> singleUserReceivers = null;
18943 boolean scannedFirstReceivers = false;
18944 for (int user : users) {
18945 // Skip users that have Shell restrictions, with exception of always permitted
18946 // Shell broadcasts
18947 if (callingUid == SHELL_UID
18948 && mUserController.hasUserRestriction(
18949 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18950 && !isPermittedShellBroadcast(intent)) {
18953 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18954 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18955 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18956 // If this is not the system user, we need to check for
18957 // any receivers that should be filtered out.
18958 for (int i=0; i<newReceivers.size(); i++) {
18959 ResolveInfo ri = newReceivers.get(i);
18960 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18961 newReceivers.remove(i);
18966 if (newReceivers != null && newReceivers.size() == 0) {
18967 newReceivers = null;
18969 if (receivers == null) {
18970 receivers = newReceivers;
18971 } else if (newReceivers != null) {
18972 // We need to concatenate the additional receivers
18973 // found with what we have do far. This would be easy,
18974 // but we also need to de-dup any receivers that are
18976 if (!scannedFirstReceivers) {
18977 // Collect any single user receivers we had already retrieved.
18978 scannedFirstReceivers = true;
18979 for (int i=0; i<receivers.size(); i++) {
18980 ResolveInfo ri = receivers.get(i);
18981 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18982 ComponentName cn = new ComponentName(
18983 ri.activityInfo.packageName, ri.activityInfo.name);
18984 if (singleUserReceivers == null) {
18985 singleUserReceivers = new HashSet<ComponentName>();
18987 singleUserReceivers.add(cn);
18991 // Add the new results to the existing results, tracking
18992 // and de-dupping single user receivers.
18993 for (int i=0; i<newReceivers.size(); i++) {
18994 ResolveInfo ri = newReceivers.get(i);
18995 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18996 ComponentName cn = new ComponentName(
18997 ri.activityInfo.packageName, ri.activityInfo.name);
18998 if (singleUserReceivers == null) {
18999 singleUserReceivers = new HashSet<ComponentName>();
19001 if (!singleUserReceivers.contains(cn)) {
19002 singleUserReceivers.add(cn);
19011 } catch (RemoteException ex) {
19012 // pm is in same process, this will never happen.
19017 private boolean isPermittedShellBroadcast(Intent intent) {
19018 // remote bugreport should always be allowed to be taken
19019 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19022 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19023 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19024 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19025 // Don't yell about broadcasts sent via shell
19029 final String action = intent.getAction();
19030 if (isProtectedBroadcast
19031 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19032 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19033 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19034 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19035 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19036 || Intent.ACTION_MASTER_CLEAR.equals(action)
19037 || Intent.ACTION_FACTORY_RESET.equals(action)
19038 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19039 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19040 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19041 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19042 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19043 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19044 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19045 // Broadcast is either protected, or it's a public action that
19046 // we've relaxed, so it's fine for system internals to send.
19050 // This broadcast may be a problem... but there are often system components that
19051 // want to send an internal broadcast to themselves, which is annoying to have to
19052 // explicitly list each action as a protected broadcast, so we will check for that
19053 // one safe case and allow it: an explicit broadcast, only being received by something
19054 // that has protected itself.
19055 if (receivers != null && receivers.size() > 0
19056 && (intent.getPackage() != null || intent.getComponent() != null)) {
19057 boolean allProtected = true;
19058 for (int i = receivers.size()-1; i >= 0; i--) {
19059 Object target = receivers.get(i);
19060 if (target instanceof ResolveInfo) {
19061 ResolveInfo ri = (ResolveInfo)target;
19062 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19063 allProtected = false;
19067 BroadcastFilter bf = (BroadcastFilter)target;
19068 if (bf.requiredPermission == null) {
19069 allProtected = false;
19074 if (allProtected) {
19080 // The vast majority of broadcasts sent from system internals
19081 // should be protected to avoid security holes, so yell loudly
19082 // to ensure we examine these cases.
19083 if (callerApp != null) {
19084 Log.wtf(TAG, "Sending non-protected broadcast " + action
19085 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19088 Log.wtf(TAG, "Sending non-protected broadcast " + action
19089 + " from system uid " + UserHandle.formatUid(callingUid)
19090 + " pkg " + callerPackage,
19095 final int broadcastIntentLocked(ProcessRecord callerApp,
19096 String callerPackage, Intent intent, String resolvedType,
19097 IIntentReceiver resultTo, int resultCode, String resultData,
19098 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19099 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19100 intent = new Intent(intent);
19102 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19103 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19104 if (callerInstantApp) {
19105 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19108 // By default broadcasts do not go to stopped apps.
19109 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19111 // If we have not finished booting, don't allow this to launch new processes.
19112 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19113 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19116 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19117 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19118 + " ordered=" + ordered + " userid=" + userId);
19119 if ((resultTo != null) && !ordered) {
19120 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19123 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19124 ALLOW_NON_FULL, "broadcast", callerPackage);
19126 // Make sure that the user who is receiving this broadcast is running.
19127 // If not, we will just skip it. Make an exception for shutdown broadcasts
19128 // and upgrade steps.
19130 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19131 if ((callingUid != SYSTEM_UID
19132 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19133 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19134 Slog.w(TAG, "Skipping broadcast of " + intent
19135 + ": user " + userId + " is stopped");
19136 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19140 BroadcastOptions brOptions = null;
19141 if (bOptions != null) {
19142 brOptions = new BroadcastOptions(bOptions);
19143 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19144 // See if the caller is allowed to do this. Note we are checking against
19145 // the actual real caller (not whoever provided the operation as say a
19146 // PendingIntent), because that who is actually supplied the arguments.
19147 if (checkComponentPermission(
19148 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19149 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19150 != PackageManager.PERMISSION_GRANTED) {
19151 String msg = "Permission Denial: " + intent.getAction()
19152 + " broadcast from " + callerPackage + " (pid=" + callingPid
19153 + ", uid=" + callingUid + ")"
19155 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19157 throw new SecurityException(msg);
19162 // Verify that protected broadcasts are only being sent by system code,
19163 // and that system code is only sending protected broadcasts.
19164 final String action = intent.getAction();
19165 final boolean isProtectedBroadcast;
19167 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19168 } catch (RemoteException e) {
19169 Slog.w(TAG, "Remote exception", e);
19170 return ActivityManager.BROADCAST_SUCCESS;
19173 final boolean isCallerSystem;
19174 switch (UserHandle.getAppId(callingUid)) {
19178 case BLUETOOTH_UID:
19180 isCallerSystem = true;
19183 isCallerSystem = (callerApp != null) && callerApp.persistent;
19187 // First line security check before anything else: stop non-system apps from
19188 // sending protected broadcasts.
19189 if (!isCallerSystem) {
19190 if (isProtectedBroadcast) {
19191 String msg = "Permission Denial: not allowed to send broadcast "
19192 + action + " from pid="
19193 + callingPid + ", uid=" + callingUid;
19195 throw new SecurityException(msg);
19197 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19198 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19199 // Special case for compatibility: we don't want apps to send this,
19200 // but historically it has not been protected and apps may be using it
19201 // to poke their own app widget. So, instead of making it protected,
19202 // just limit it to the caller.
19203 if (callerPackage == null) {
19204 String msg = "Permission Denial: not allowed to send broadcast "
19205 + action + " from unknown caller.";
19207 throw new SecurityException(msg);
19208 } else if (intent.getComponent() != null) {
19209 // They are good enough to send to an explicit component... verify
19210 // it is being sent to the calling app.
19211 if (!intent.getComponent().getPackageName().equals(
19213 String msg = "Permission Denial: not allowed to send broadcast "
19215 + intent.getComponent().getPackageName() + " from "
19218 throw new SecurityException(msg);
19221 // Limit broadcast to their own package.
19222 intent.setPackage(callerPackage);
19227 if (action != null) {
19228 if (getBackgroundLaunchBroadcasts().contains(action)) {
19229 if (DEBUG_BACKGROUND_CHECK) {
19230 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19232 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19236 case Intent.ACTION_UID_REMOVED:
19237 case Intent.ACTION_PACKAGE_REMOVED:
19238 case Intent.ACTION_PACKAGE_CHANGED:
19239 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19240 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19241 case Intent.ACTION_PACKAGES_SUSPENDED:
19242 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19243 // Handle special intents: if this broadcast is from the package
19244 // manager about a package being removed, we need to remove all of
19245 // its activities from the history stack.
19246 if (checkComponentPermission(
19247 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19248 callingPid, callingUid, -1, true)
19249 != PackageManager.PERMISSION_GRANTED) {
19250 String msg = "Permission Denial: " + intent.getAction()
19251 + " broadcast from " + callerPackage + " (pid=" + callingPid
19252 + ", uid=" + callingUid + ")"
19254 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19256 throw new SecurityException(msg);
19259 case Intent.ACTION_UID_REMOVED:
19260 final int uid = getUidFromIntent(intent);
19262 mBatteryStatsService.removeUid(uid);
19263 mAppOpsService.uidRemoved(uid);
19266 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19267 // If resources are unavailable just force stop all those packages
19268 // and flush the attribute cache as well.
19270 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19271 if (list != null && list.length > 0) {
19272 for (int i = 0; i < list.length; i++) {
19273 forceStopPackageLocked(list[i], -1, false, true, true,
19274 false, false, userId, "storage unmount");
19276 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19277 sendPackageBroadcastLocked(
19278 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19282 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19283 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19285 case Intent.ACTION_PACKAGE_REMOVED:
19286 case Intent.ACTION_PACKAGE_CHANGED:
19287 Uri data = intent.getData();
19289 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19290 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19291 final boolean replacing =
19292 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19293 final boolean killProcess =
19294 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19295 final boolean fullUninstall = removed && !replacing;
19298 forceStopPackageLocked(ssp, UserHandle.getAppId(
19299 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19300 false, true, true, false, fullUninstall, userId,
19301 removed ? "pkg removed" : "pkg changed");
19303 final int cmd = killProcess
19304 ? ApplicationThreadConstants.PACKAGE_REMOVED
19305 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19306 sendPackageBroadcastLocked(cmd,
19307 new String[] {ssp}, userId);
19308 if (fullUninstall) {
19309 mAppOpsService.packageRemoved(
19310 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19312 // Remove all permissions granted from/to this package
19313 removeUriPermissionsForPackageLocked(ssp, userId, true);
19315 removeTasksByPackageNameLocked(ssp, userId);
19317 mServices.forceStopPackageLocked(ssp, userId);
19319 // Hide the "unsupported display" dialog if necessary.
19320 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19321 mUnsupportedDisplaySizeDialog.getPackageName())) {
19322 mUnsupportedDisplaySizeDialog.dismiss();
19323 mUnsupportedDisplaySizeDialog = null;
19325 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19326 mBatteryStatsService.notePackageUninstalled(ssp);
19330 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19331 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19332 userId, ProcessList.INVALID_ADJ,
19333 false, true, true, false, "change " + ssp);
19335 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19336 intent.getStringArrayExtra(
19337 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19341 case Intent.ACTION_PACKAGES_SUSPENDED:
19342 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19343 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19344 intent.getAction());
19345 final String[] packageNames = intent.getStringArrayExtra(
19346 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19347 final int userHandle = intent.getIntExtra(
19348 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19350 synchronized(ActivityManagerService.this) {
19351 mRecentTasks.onPackagesSuspendedChanged(
19352 packageNames, suspended, userHandle);
19357 case Intent.ACTION_PACKAGE_REPLACED:
19359 final Uri data = intent.getData();
19361 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19362 ApplicationInfo aInfo = null;
19364 aInfo = AppGlobals.getPackageManager()
19365 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19366 } catch (RemoteException ignore) {}
19367 if (aInfo == null) {
19368 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19369 + " ssp=" + ssp + " data=" + data);
19370 return ActivityManager.BROADCAST_SUCCESS;
19372 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19373 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19374 new String[] {ssp}, userId);
19378 case Intent.ACTION_PACKAGE_ADDED:
19380 // Special case for adding a package: by default turn on compatibility mode.
19381 Uri data = intent.getData();
19383 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19384 final boolean replacing =
19385 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19386 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19389 ApplicationInfo ai = AppGlobals.getPackageManager().
19390 getApplicationInfo(ssp, 0, 0);
19391 mBatteryStatsService.notePackageInstalled(ssp,
19392 ai != null ? ai.versionCode : 0);
19393 } catch (RemoteException e) {
19398 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19400 Uri data = intent.getData();
19402 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19403 // Hide the "unsupported display" dialog if necessary.
19404 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19405 mUnsupportedDisplaySizeDialog.getPackageName())) {
19406 mUnsupportedDisplaySizeDialog.dismiss();
19407 mUnsupportedDisplaySizeDialog = null;
19409 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19413 case Intent.ACTION_TIMEZONE_CHANGED:
19414 // If this is the time zone changed action, queue up a message that will reset
19415 // the timezone of all currently running processes. This message will get
19416 // queued up before the broadcast happens.
19417 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19419 case Intent.ACTION_TIME_CHANGED:
19420 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19421 // the tri-state value it may contain and "unknown".
19422 // For convenience we re-use the Intent extra values.
19423 final int NO_EXTRA_VALUE_FOUND = -1;
19424 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19425 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19426 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19427 // Only send a message if the time preference is available.
19428 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19429 Message updateTimePreferenceMsg =
19430 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19431 timeFormatPreferenceMsgValue, 0);
19432 mHandler.sendMessage(updateTimePreferenceMsg);
19434 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19435 synchronized (stats) {
19436 stats.noteCurrentTimeChangedLocked();
19439 case Intent.ACTION_CLEAR_DNS_CACHE:
19440 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19442 case Proxy.PROXY_CHANGE_ACTION:
19443 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19444 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19446 case android.hardware.Camera.ACTION_NEW_PICTURE:
19447 case android.hardware.Camera.ACTION_NEW_VIDEO:
19448 // In N we just turned these off; in O we are turing them back on partly,
19449 // only for registered receivers. This will still address the main problem
19450 // (a spam of apps waking up when a picture is taken putting significant
19451 // memory pressure on the system at a bad point), while still allowing apps
19452 // that are already actively running to know about this happening.
19453 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19455 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19456 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19458 case "com.android.launcher.action.INSTALL_SHORTCUT":
19459 // As of O, we no longer support this broadcasts, even for pre-O apps.
19460 // Apps should now be using ShortcutManager.pinRequestShortcut().
19461 Log.w(TAG, "Broadcast " + action
19462 + " no longer supported. It will not be delivered.");
19463 return ActivityManager.BROADCAST_SUCCESS;
19466 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19467 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19468 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19469 final int uid = getUidFromIntent(intent);
19471 final UidRecord uidRec = mActiveUids.get(uid);
19472 if (uidRec != null) {
19473 uidRec.updateHasInternetPermission();
19479 // Add to the sticky list if requested.
19481 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19482 callingPid, callingUid)
19483 != PackageManager.PERMISSION_GRANTED) {
19484 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19485 + callingPid + ", uid=" + callingUid
19486 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19488 throw new SecurityException(msg);
19490 if (requiredPermissions != null && requiredPermissions.length > 0) {
19491 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19492 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19493 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19495 if (intent.getComponent() != null) {
19496 throw new SecurityException(
19497 "Sticky broadcasts can't target a specific component");
19499 // We use userId directly here, since the "all" target is maintained
19500 // as a separate set of sticky broadcasts.
19501 if (userId != UserHandle.USER_ALL) {
19502 // But first, if this is not a broadcast to all users, then
19503 // make sure it doesn't conflict with an existing broadcast to
19505 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19506 UserHandle.USER_ALL);
19507 if (stickies != null) {
19508 ArrayList<Intent> list = stickies.get(intent.getAction());
19509 if (list != null) {
19510 int N = list.size();
19512 for (i=0; i<N; i++) {
19513 if (intent.filterEquals(list.get(i))) {
19514 throw new IllegalArgumentException(
19515 "Sticky broadcast " + intent + " for user "
19516 + userId + " conflicts with existing global broadcast");
19522 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19523 if (stickies == null) {
19524 stickies = new ArrayMap<>();
19525 mStickyBroadcasts.put(userId, stickies);
19527 ArrayList<Intent> list = stickies.get(intent.getAction());
19528 if (list == null) {
19529 list = new ArrayList<>();
19530 stickies.put(intent.getAction(), list);
19532 final int stickiesCount = list.size();
19534 for (i = 0; i < stickiesCount; i++) {
19535 if (intent.filterEquals(list.get(i))) {
19536 // This sticky already exists, replace it.
19537 list.set(i, new Intent(intent));
19541 if (i >= stickiesCount) {
19542 list.add(new Intent(intent));
19547 if (userId == UserHandle.USER_ALL) {
19548 // Caller wants broadcast to go to all started users.
19549 users = mUserController.getStartedUserArrayLocked();
19551 // Caller wants broadcast to go to one specific user.
19552 users = new int[] {userId};
19555 // Figure out who all will receive this broadcast.
19556 List receivers = null;
19557 List<BroadcastFilter> registeredReceivers = null;
19558 // Need to resolve the intent to interested receivers...
19559 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19561 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19563 if (intent.getComponent() == null) {
19564 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19565 // Query one target user at a time, excluding shell-restricted users
19566 for (int i = 0; i < users.length; i++) {
19567 if (mUserController.hasUserRestriction(
19568 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19571 List<BroadcastFilter> registeredReceiversForUser =
19572 mReceiverResolver.queryIntent(intent,
19573 resolvedType, false /*defaultOnly*/, users[i]);
19574 if (registeredReceivers == null) {
19575 registeredReceivers = registeredReceiversForUser;
19576 } else if (registeredReceiversForUser != null) {
19577 registeredReceivers.addAll(registeredReceiversForUser);
19581 registeredReceivers = mReceiverResolver.queryIntent(intent,
19582 resolvedType, false /*defaultOnly*/, userId);
19586 final boolean replacePending =
19587 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19589 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19590 + " replacePending=" + replacePending);
19592 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19593 if (!ordered && NR > 0) {
19594 // If we are not serializing this broadcast, then send the
19595 // registered receivers separately so they don't wait for the
19596 // components to be launched.
19597 if (isCallerSystem) {
19598 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19599 isProtectedBroadcast, registeredReceivers);
19601 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19602 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19603 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19604 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19605 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19606 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19607 final boolean replaced = replacePending
19608 && (queue.replaceParallelBroadcastLocked(r) != null);
19609 // Note: We assume resultTo is null for non-ordered broadcasts.
19611 queue.enqueueParallelBroadcastLocked(r);
19612 queue.scheduleBroadcastsLocked();
19614 registeredReceivers = null;
19618 // Merge into one list.
19620 if (receivers != null) {
19621 // A special case for PACKAGE_ADDED: do not allow the package
19622 // being added to see this broadcast. This prevents them from
19623 // using this as a back door to get run as soon as they are
19624 // installed. Maybe in the future we want to have a special install
19625 // broadcast or such for apps, but we'd like to deliberately make
19627 String skipPackages[] = null;
19628 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19629 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19630 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19631 Uri data = intent.getData();
19632 if (data != null) {
19633 String pkgName = data.getSchemeSpecificPart();
19634 if (pkgName != null) {
19635 skipPackages = new String[] { pkgName };
19638 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19639 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19641 if (skipPackages != null && (skipPackages.length > 0)) {
19642 for (String skipPackage : skipPackages) {
19643 if (skipPackage != null) {
19644 int NT = receivers.size();
19645 for (int it=0; it<NT; it++) {
19646 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19647 if (curt.activityInfo.packageName.equals(skipPackage)) {
19648 receivers.remove(it);
19657 int NT = receivers != null ? receivers.size() : 0;
19659 ResolveInfo curt = null;
19660 BroadcastFilter curr = null;
19661 while (it < NT && ir < NR) {
19662 if (curt == null) {
19663 curt = (ResolveInfo)receivers.get(it);
19665 if (curr == null) {
19666 curr = registeredReceivers.get(ir);
19668 if (curr.getPriority() >= curt.priority) {
19669 // Insert this broadcast record into the final list.
19670 receivers.add(it, curr);
19676 // Skip to the next ResolveInfo in the final list.
19683 if (receivers == null) {
19684 receivers = new ArrayList();
19686 receivers.add(registeredReceivers.get(ir));
19690 if (isCallerSystem) {
19691 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19692 isProtectedBroadcast, receivers);
19695 if ((receivers != null && receivers.size() > 0)
19696 || resultTo != null) {
19697 BroadcastQueue queue = broadcastQueueForIntent(intent);
19698 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19699 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19700 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19701 resultData, resultExtras, ordered, sticky, false, userId);
19703 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19704 + ": prev had " + queue.mOrderedBroadcasts.size());
19705 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19706 "Enqueueing broadcast " + r.intent.getAction());
19708 final BroadcastRecord oldRecord =
19709 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19710 if (oldRecord != null) {
19711 // Replaced, fire the result-to receiver.
19712 if (oldRecord.resultTo != null) {
19713 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19715 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19717 Activity.RESULT_CANCELED, null, null,
19718 false, false, oldRecord.userId);
19719 } catch (RemoteException e) {
19720 Slog.w(TAG, "Failure ["
19721 + queue.mQueueName + "] sending broadcast result of "
19727 queue.enqueueOrderedBroadcastLocked(r);
19728 queue.scheduleBroadcastsLocked();
19731 // There was nobody interested in the broadcast, but we still want to record
19732 // that it happened.
19733 if (intent.getComponent() == null && intent.getPackage() == null
19734 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19735 // This was an implicit broadcast... let's record it for posterity.
19736 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19740 return ActivityManager.BROADCAST_SUCCESS;
19744 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19746 private int getUidFromIntent(Intent intent) {
19747 if (intent == null) {
19750 final Bundle intentExtras = intent.getExtras();
19751 return intent.hasExtra(Intent.EXTRA_UID)
19752 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19755 final void rotateBroadcastStatsIfNeededLocked() {
19756 final long now = SystemClock.elapsedRealtime();
19757 if (mCurBroadcastStats == null ||
19758 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19759 mLastBroadcastStats = mCurBroadcastStats;
19760 if (mLastBroadcastStats != null) {
19761 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19762 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19764 mCurBroadcastStats = new BroadcastStats();
19768 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19769 int skipCount, long dispatchTime) {
19770 rotateBroadcastStatsIfNeededLocked();
19771 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19774 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19775 rotateBroadcastStatsIfNeededLocked();
19776 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19779 final Intent verifyBroadcastLocked(Intent intent) {
19780 // Refuse possible leaked file descriptors
19781 if (intent != null && intent.hasFileDescriptors() == true) {
19782 throw new IllegalArgumentException("File descriptors passed in Intent");
19785 int flags = intent.getFlags();
19787 if (!mProcessesReady) {
19788 // if the caller really truly claims to know what they're doing, go
19789 // ahead and allow the broadcast without launching any receivers
19790 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19791 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19792 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19793 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19794 + " before boot completion");
19795 throw new IllegalStateException("Cannot broadcast before boot completed");
19799 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19800 throw new IllegalArgumentException(
19801 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19804 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19805 switch (Binder.getCallingUid()) {
19810 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19811 + Binder.getCallingUid());
19812 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19820 public final int broadcastIntent(IApplicationThread caller,
19821 Intent intent, String resolvedType, IIntentReceiver resultTo,
19822 int resultCode, String resultData, Bundle resultExtras,
19823 String[] requiredPermissions, int appOp, Bundle bOptions,
19824 boolean serialized, boolean sticky, int userId) {
19825 enforceNotIsolatedCaller("broadcastIntent");
19826 synchronized(this) {
19827 intent = verifyBroadcastLocked(intent);
19829 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19830 final int callingPid = Binder.getCallingPid();
19831 final int callingUid = Binder.getCallingUid();
19832 final long origId = Binder.clearCallingIdentity();
19833 int res = broadcastIntentLocked(callerApp,
19834 callerApp != null ? callerApp.info.packageName : null,
19835 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19836 requiredPermissions, appOp, bOptions, serialized, sticky,
19837 callingPid, callingUid, userId);
19838 Binder.restoreCallingIdentity(origId);
19844 int broadcastIntentInPackage(String packageName, int uid,
19845 Intent intent, String resolvedType, IIntentReceiver resultTo,
19846 int resultCode, String resultData, Bundle resultExtras,
19847 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19849 synchronized(this) {
19850 intent = verifyBroadcastLocked(intent);
19852 final long origId = Binder.clearCallingIdentity();
19853 String[] requiredPermissions = requiredPermission == null ? null
19854 : new String[] {requiredPermission};
19855 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19856 resultTo, resultCode, resultData, resultExtras,
19857 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19858 sticky, -1, uid, userId);
19859 Binder.restoreCallingIdentity(origId);
19864 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19865 // Refuse possible leaked file descriptors
19866 if (intent != null && intent.hasFileDescriptors() == true) {
19867 throw new IllegalArgumentException("File descriptors passed in Intent");
19870 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19871 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19873 synchronized(this) {
19874 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19875 != PackageManager.PERMISSION_GRANTED) {
19876 String msg = "Permission Denial: unbroadcastIntent() from pid="
19877 + Binder.getCallingPid()
19878 + ", uid=" + Binder.getCallingUid()
19879 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19881 throw new SecurityException(msg);
19883 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19884 if (stickies != null) {
19885 ArrayList<Intent> list = stickies.get(intent.getAction());
19886 if (list != null) {
19887 int N = list.size();
19889 for (i=0; i<N; i++) {
19890 if (intent.filterEquals(list.get(i))) {
19895 if (list.size() <= 0) {
19896 stickies.remove(intent.getAction());
19899 if (stickies.size() <= 0) {
19900 mStickyBroadcasts.remove(userId);
19906 void backgroundServicesFinishedLocked(int userId) {
19907 for (BroadcastQueue queue : mBroadcastQueues) {
19908 queue.backgroundServicesFinishedLocked(userId);
19912 public void finishReceiver(IBinder who, int resultCode, String resultData,
19913 Bundle resultExtras, boolean resultAbort, int flags) {
19914 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19916 // Refuse possible leaked file descriptors
19917 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19918 throw new IllegalArgumentException("File descriptors passed in Bundle");
19921 final long origId = Binder.clearCallingIdentity();
19923 boolean doNext = false;
19926 synchronized(this) {
19927 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19928 ? mFgBroadcastQueue : mBgBroadcastQueue;
19929 r = queue.getMatchingOrderedReceiver(who);
19931 doNext = r.queue.finishReceiverLocked(r, resultCode,
19932 resultData, resultExtras, resultAbort, true);
19937 r.queue.processNextBroadcast(false);
19939 trimApplications();
19941 Binder.restoreCallingIdentity(origId);
19945 // =========================================================
19947 // =========================================================
19949 public boolean startInstrumentation(ComponentName className,
19950 String profileFile, int flags, Bundle arguments,
19951 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19952 int userId, String abiOverride) {
19953 enforceNotIsolatedCaller("startInstrumentation");
19954 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19955 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19956 // Refuse possible leaked file descriptors
19957 if (arguments != null && arguments.hasFileDescriptors()) {
19958 throw new IllegalArgumentException("File descriptors passed in Bundle");
19961 synchronized(this) {
19962 InstrumentationInfo ii = null;
19963 ApplicationInfo ai = null;
19965 ii = mContext.getPackageManager().getInstrumentationInfo(
19966 className, STOCK_PM_FLAGS);
19967 ai = AppGlobals.getPackageManager().getApplicationInfo(
19968 ii.targetPackage, STOCK_PM_FLAGS, userId);
19969 } catch (PackageManager.NameNotFoundException e) {
19970 } catch (RemoteException e) {
19973 reportStartInstrumentationFailureLocked(watcher, className,
19974 "Unable to find instrumentation info for: " + className);
19978 reportStartInstrumentationFailureLocked(watcher, className,
19979 "Unable to find instrumentation target package: " + ii.targetPackage);
19982 if (!ai.hasCode()) {
19983 reportStartInstrumentationFailureLocked(watcher, className,
19984 "Instrumentation target has no code: " + ii.targetPackage);
19988 int match = mContext.getPackageManager().checkSignatures(
19989 ii.targetPackage, ii.packageName);
19990 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19991 String msg = "Permission Denial: starting instrumentation "
19992 + className + " from pid="
19993 + Binder.getCallingPid()
19994 + ", uid=" + Binder.getCallingPid()
19995 + " not allowed because package " + ii.packageName
19996 + " does not have a signature matching the target "
19997 + ii.targetPackage;
19998 reportStartInstrumentationFailureLocked(watcher, className, msg);
19999 throw new SecurityException(msg);
20002 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20003 activeInstr.mClass = className;
20004 String defProcess = ai.processName;;
20005 if (ii.targetProcesses == null) {
20006 activeInstr.mTargetProcesses = new String[]{ai.processName};
20007 } else if (ii.targetProcesses.equals("*")) {
20008 activeInstr.mTargetProcesses = new String[0];
20010 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20011 defProcess = activeInstr.mTargetProcesses[0];
20013 activeInstr.mTargetInfo = ai;
20014 activeInstr.mProfileFile = profileFile;
20015 activeInstr.mArguments = arguments;
20016 activeInstr.mWatcher = watcher;
20017 activeInstr.mUiAutomationConnection = uiAutomationConnection;
20018 activeInstr.mResultClass = className;
20020 final long origId = Binder.clearCallingIdentity();
20021 // Instrumentation can kill and relaunch even persistent processes
20022 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20024 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20025 app.instr = activeInstr;
20026 activeInstr.mFinished = false;
20027 activeInstr.mRunningProcesses.add(app);
20028 if (!mActiveInstrumentation.contains(activeInstr)) {
20029 mActiveInstrumentation.add(activeInstr);
20031 Binder.restoreCallingIdentity(origId);
20038 * Report errors that occur while attempting to start Instrumentation. Always writes the
20039 * error to the logs, but if somebody is watching, send the report there too. This enables
20040 * the "am" command to report errors with more information.
20042 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
20043 * @param cn The component name of the instrumentation.
20044 * @param report The error report.
20046 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20047 ComponentName cn, String report) {
20048 Slog.w(TAG, report);
20049 if (watcher != null) {
20050 Bundle results = new Bundle();
20051 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20052 results.putString("Error", report);
20053 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20057 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20058 if (app.instr == null) {
20059 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20063 if (!app.instr.mFinished && results != null) {
20064 if (app.instr.mCurResults == null) {
20065 app.instr.mCurResults = new Bundle(results);
20067 app.instr.mCurResults.putAll(results);
20072 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20073 int userId = UserHandle.getCallingUserId();
20074 // Refuse possible leaked file descriptors
20075 if (results != null && results.hasFileDescriptors()) {
20076 throw new IllegalArgumentException("File descriptors passed in Intent");
20079 synchronized(this) {
20080 ProcessRecord app = getRecordForAppLocked(target);
20082 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20085 final long origId = Binder.clearCallingIdentity();
20086 addInstrumentationResultsLocked(app, results);
20087 Binder.restoreCallingIdentity(origId);
20091 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20092 if (app.instr == null) {
20093 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20097 if (!app.instr.mFinished) {
20098 if (app.instr.mWatcher != null) {
20099 Bundle finalResults = app.instr.mCurResults;
20100 if (finalResults != null) {
20101 if (app.instr.mCurResults != null && results != null) {
20102 finalResults.putAll(results);
20105 finalResults = results;
20107 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20108 app.instr.mClass, resultCode, finalResults);
20111 // Can't call out of the system process with a lock held, so post a message.
20112 if (app.instr.mUiAutomationConnection != null) {
20113 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20114 app.instr.mUiAutomationConnection).sendToTarget();
20116 app.instr.mFinished = true;
20119 app.instr.removeProcess(app);
20122 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20126 public void finishInstrumentation(IApplicationThread target,
20127 int resultCode, Bundle results) {
20128 int userId = UserHandle.getCallingUserId();
20129 // Refuse possible leaked file descriptors
20130 if (results != null && results.hasFileDescriptors()) {
20131 throw new IllegalArgumentException("File descriptors passed in Intent");
20134 synchronized(this) {
20135 ProcessRecord app = getRecordForAppLocked(target);
20137 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20140 final long origId = Binder.clearCallingIdentity();
20141 finishInstrumentationLocked(app, resultCode, results);
20142 Binder.restoreCallingIdentity(origId);
20146 // =========================================================
20148 // =========================================================
20150 public ConfigurationInfo getDeviceConfigurationInfo() {
20151 ConfigurationInfo config = new ConfigurationInfo();
20152 synchronized (this) {
20153 final Configuration globalConfig = getGlobalConfiguration();
20154 config.reqTouchScreen = globalConfig.touchscreen;
20155 config.reqKeyboardType = globalConfig.keyboard;
20156 config.reqNavigation = globalConfig.navigation;
20157 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20158 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20159 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20161 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20162 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20163 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20165 config.reqGlEsVersion = GL_ES_VERSION;
20170 ActivityStack getFocusedStack() {
20171 return mStackSupervisor.getFocusedStack();
20175 public int getFocusedStackId() throws RemoteException {
20176 ActivityStack focusedStack = getFocusedStack();
20177 if (focusedStack != null) {
20178 return focusedStack.getStackId();
20183 public Configuration getConfiguration() {
20185 synchronized(this) {
20186 ci = new Configuration(getGlobalConfiguration());
20187 ci.userSetLocale = false;
20193 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20194 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20195 synchronized (this) {
20196 mSuppressResizeConfigChanges = suppress;
20201 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20202 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20203 * activity and clearing the task at the same time.
20206 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20207 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20208 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20209 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20211 synchronized (this) {
20212 final long origId = Binder.clearCallingIdentity();
20214 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20216 Binder.restoreCallingIdentity(origId);
20222 public void updatePersistentConfiguration(Configuration values) {
20223 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20224 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20225 if (values == null) {
20226 throw new NullPointerException("Configuration must not be null");
20229 int userId = UserHandle.getCallingUserId();
20231 synchronized(this) {
20232 updatePersistentConfigurationLocked(values, userId);
20236 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20237 final long origId = Binder.clearCallingIdentity();
20239 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20241 Binder.restoreCallingIdentity(origId);
20245 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20246 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20247 FONT_SCALE, 1.0f, userId);
20249 synchronized (this) {
20250 if (getGlobalConfiguration().fontScale == scaleFactor) {
20254 final Configuration configuration
20255 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20256 configuration.fontScale = scaleFactor;
20257 updatePersistentConfigurationLocked(configuration, userId);
20261 private void enforceWriteSettingsPermission(String func) {
20262 int uid = Binder.getCallingUid();
20263 if (uid == ROOT_UID) {
20267 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20268 Settings.getPackageNameForUid(mContext, uid), false)) {
20272 String msg = "Permission Denial: " + func + " from pid="
20273 + Binder.getCallingPid()
20275 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20277 throw new SecurityException(msg);
20281 public boolean updateConfiguration(Configuration values) {
20282 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20284 synchronized(this) {
20285 if (values == null && mWindowManager != null) {
20286 // sentinel: fetch the current configuration from the window manager
20287 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20290 if (mWindowManager != null) {
20291 // Update OOM levels based on display size.
20292 mProcessList.applyDisplaySize(mWindowManager);
20295 final long origId = Binder.clearCallingIdentity();
20297 if (values != null) {
20298 Settings.System.clearConfiguration(values);
20300 updateConfigurationLocked(values, null, false, false /* persistent */,
20301 UserHandle.USER_NULL, false /* deferResume */,
20302 mTmpUpdateConfigurationResult);
20303 return mTmpUpdateConfigurationResult.changes != 0;
20305 Binder.restoreCallingIdentity(origId);
20310 void updateUserConfigurationLocked() {
20311 final Configuration configuration = new Configuration(getGlobalConfiguration());
20312 final int currentUserId = mUserController.getCurrentUserIdLocked();
20313 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20314 currentUserId, Settings.System.canWrite(mContext));
20315 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20316 false /* persistent */, currentUserId, false /* deferResume */);
20319 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20320 boolean initLocale) {
20321 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20324 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20325 boolean initLocale, boolean deferResume) {
20326 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20327 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20328 UserHandle.USER_NULL, deferResume);
20331 // To cache the list of supported system locales
20332 private String[] mSupportedSystemLocales = null;
20334 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20335 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20336 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20337 deferResume, null /* result */);
20341 * Do either or both things: (1) change the current configuration, and (2)
20342 * make sure the given activity is running with the (now) current
20343 * configuration. Returns true if the activity has been left running, or
20344 * false if <var>starting</var> is being destroyed to match the new
20347 * @param userId is only used when persistent parameter is set to true to persist configuration
20348 * for that particular user
20350 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20351 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20352 UpdateConfigurationResult result) {
20354 boolean kept = true;
20356 if (mWindowManager != null) {
20357 mWindowManager.deferSurfaceLayout();
20360 if (values != null) {
20361 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20365 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20367 if (mWindowManager != null) {
20368 mWindowManager.continueSurfaceLayout();
20372 if (result != null) {
20373 result.changes = changes;
20374 result.activityRelaunched = !kept;
20379 /** Update default (global) configuration and notify listeners about changes. */
20380 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20381 boolean persistent, int userId, boolean deferResume) {
20382 mTempConfig.setTo(getGlobalConfiguration());
20383 final int changes = mTempConfig.updateFrom(values);
20384 if (changes == 0) {
20385 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20386 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20387 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20388 // (even if there are no actual changes) to unfreeze the window.
20389 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20393 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20394 "Updating global configuration to: " + values);
20396 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20398 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20399 final LocaleList locales = values.getLocales();
20400 int bestLocaleIndex = 0;
20401 if (locales.size() > 1) {
20402 if (mSupportedSystemLocales == null) {
20403 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20405 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20407 SystemProperties.set("persist.sys.locale",
20408 locales.get(bestLocaleIndex).toLanguageTag());
20409 LocaleList.setDefault(locales, bestLocaleIndex);
20410 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20411 locales.get(bestLocaleIndex)));
20414 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20415 mTempConfig.seq = mConfigurationSeq;
20417 // Update stored global config and notify everyone about the change.
20418 mStackSupervisor.onConfigurationChanged(mTempConfig);
20420 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20421 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20422 mUsageStatsService.reportConfigurationChange(mTempConfig,
20423 mUserController.getCurrentUserIdLocked());
20425 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20426 mShowDialogs = shouldShowDialogs(mTempConfig);
20428 AttributeCache ac = AttributeCache.instance();
20430 ac.updateConfiguration(mTempConfig);
20433 // Make sure all resources in our process are updated right now, so that anyone who is going
20434 // to retrieve resource values after we return will be sure to get the new ones. This is
20435 // especially important during boot, where the first config change needs to guarantee all
20436 // resources have that config before following boot code is executed.
20437 mSystemThread.applyConfigurationToResources(mTempConfig);
20439 // We need another copy of global config because we're scheduling some calls instead of
20440 // running them in place. We need to be sure that object we send will be handled unchanged.
20441 final Configuration configCopy = new Configuration(mTempConfig);
20442 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20443 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20444 msg.obj = configCopy;
20446 mHandler.sendMessage(msg);
20449 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20450 ProcessRecord app = mLruProcesses.get(i);
20452 if (app.thread != null) {
20453 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20454 + app.processName + " new config " + configCopy);
20455 app.thread.scheduleConfigurationChanged(configCopy);
20457 } catch (Exception e) {
20461 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20462 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20463 | Intent.FLAG_RECEIVER_FOREGROUND
20464 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20465 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20466 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20467 UserHandle.USER_ALL);
20468 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20469 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20470 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20471 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20472 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20473 if (initLocale || !mProcessesReady) {
20474 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20476 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20477 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20478 UserHandle.USER_ALL);
20481 // Override configuration of the default display duplicates global config, so we need to
20482 // update it also. This will also notify WindowManager about changes.
20483 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20490 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20491 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20493 synchronized (this) {
20494 // Check if display is initialized in AM.
20495 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20496 // Call might come when display is not yet added or has already been removed.
20497 if (DEBUG_CONFIGURATION) {
20498 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20504 if (values == null && mWindowManager != null) {
20505 // sentinel: fetch the current configuration from the window manager
20506 values = mWindowManager.computeNewConfiguration(displayId);
20509 if (mWindowManager != null) {
20510 // Update OOM levels based on display size.
20511 mProcessList.applyDisplaySize(mWindowManager);
20514 final long origId = Binder.clearCallingIdentity();
20516 if (values != null) {
20517 Settings.System.clearConfiguration(values);
20519 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20520 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20521 return mTmpUpdateConfigurationResult.changes != 0;
20523 Binder.restoreCallingIdentity(origId);
20528 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20529 boolean deferResume, int displayId) {
20530 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20531 displayId, null /* result */);
20535 * Updates override configuration specific for the selected display. If no config is provided,
20536 * new one will be computed in WM based on current display info.
20538 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20539 ActivityRecord starting, boolean deferResume, int displayId,
20540 UpdateConfigurationResult result) {
20542 boolean kept = true;
20544 if (mWindowManager != null) {
20545 mWindowManager.deferSurfaceLayout();
20548 if (values != null) {
20549 if (displayId == DEFAULT_DISPLAY) {
20550 // Override configuration of the default display duplicates global config, so
20551 // we're calling global config update instead for default display. It will also
20552 // apply the correct override config.
20553 changes = updateGlobalConfiguration(values, false /* initLocale */,
20554 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20556 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20560 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20562 if (mWindowManager != null) {
20563 mWindowManager.continueSurfaceLayout();
20567 if (result != null) {
20568 result.changes = changes;
20569 result.activityRelaunched = !kept;
20574 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20576 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20577 final int changes = mTempConfig.updateFrom(values);
20578 if (changes != 0) {
20579 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20580 + mTempConfig + " for displayId=" + displayId);
20581 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20583 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20584 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20585 // Reset the unsupported display size dialog.
20586 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20588 killAllBackgroundProcessesExcept(N,
20589 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20593 // Update the configuration with WM first and check if any of the stacks need to be resized
20594 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20595 // necessary. This way we don't need to relaunch again afterwards in
20596 // ensureActivityConfigurationLocked().
20597 if (mWindowManager != null) {
20598 final int[] resizedStacks =
20599 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20600 if (resizedStacks != null) {
20601 for (int stackId : resizedStacks) {
20602 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20610 /** Applies latest configuration and/or visibility updates if needed. */
20611 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20612 boolean kept = true;
20613 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20614 // mainStack is null during startup.
20615 if (mainStack != null) {
20616 if (changes != 0 && starting == null) {
20617 // If the configuration changed, and the caller is not already
20618 // in the process of starting an activity, then find the top
20619 // activity to check if its configuration needs to change.
20620 starting = mainStack.topRunningActivityLocked();
20623 if (starting != null) {
20624 kept = starting.ensureActivityConfigurationLocked(changes,
20625 false /* preserveWindow */);
20626 // And we need to make sure at this point that all other activities
20627 // are made visible with the correct configuration.
20628 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20629 !PRESERVE_WINDOWS);
20636 /** Helper method that requests bounds from WM and applies them to stack. */
20637 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20638 final Rect newStackBounds = new Rect();
20639 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20640 mStackSupervisor.resizeStackLocked(
20641 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20642 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20643 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20647 * Decide based on the configuration whether we should show the ANR,
20648 * crash, etc dialogs. The idea is that if there is no affordance to
20649 * press the on-screen buttons, or the user experience would be more
20650 * greatly impacted than the crash itself, we shouldn't show the dialog.
20652 * A thought: SystemUI might also want to get told about this, the Power
20653 * dialog / global actions also might want different behaviors.
20655 private static boolean shouldShowDialogs(Configuration config) {
20656 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20657 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20658 && config.navigation == Configuration.NAVIGATION_NONAV);
20659 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20660 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20661 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20662 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20663 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20664 return inputMethodExists && uiModeSupportsDialogs;
20668 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20669 synchronized (this) {
20670 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20671 if (srec != null) {
20672 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20678 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20679 Intent resultData) {
20681 synchronized (this) {
20682 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20684 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20690 public int getLaunchedFromUid(IBinder activityToken) {
20691 ActivityRecord srec;
20692 synchronized (this) {
20693 srec = ActivityRecord.forTokenLocked(activityToken);
20695 if (srec == null) {
20698 return srec.launchedFromUid;
20701 public String getLaunchedFromPackage(IBinder activityToken) {
20702 ActivityRecord srec;
20703 synchronized (this) {
20704 srec = ActivityRecord.forTokenLocked(activityToken);
20706 if (srec == null) {
20709 return srec.launchedFromPackage;
20712 // =========================================================
20713 // LIFETIME MANAGEMENT
20714 // =========================================================
20716 // Returns whether the app is receiving broadcast.
20717 // If receiving, fetch all broadcast queues which the app is
20718 // the current [or imminent] receiver on.
20719 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20720 ArraySet<BroadcastQueue> receivingQueues) {
20721 if (!app.curReceivers.isEmpty()) {
20722 for (BroadcastRecord r : app.curReceivers) {
20723 receivingQueues.add(r.queue);
20728 // It's not the current receiver, but it might be starting up to become one
20729 for (BroadcastQueue queue : mBroadcastQueues) {
20730 final BroadcastRecord r = queue.mPendingBroadcast;
20731 if (r != null && r.curApp == app) {
20732 // found it; report which queue it's in
20733 receivingQueues.add(queue);
20737 return !receivingQueues.isEmpty();
20740 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20741 int targetUid, ComponentName targetComponent, String targetProcess) {
20742 if (!mTrackingAssociations) {
20745 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20746 = mAssociations.get(targetUid);
20747 if (components == null) {
20748 components = new ArrayMap<>();
20749 mAssociations.put(targetUid, components);
20751 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20752 if (sourceUids == null) {
20753 sourceUids = new SparseArray<>();
20754 components.put(targetComponent, sourceUids);
20756 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20757 if (sourceProcesses == null) {
20758 sourceProcesses = new ArrayMap<>();
20759 sourceUids.put(sourceUid, sourceProcesses);
20761 Association ass = sourceProcesses.get(sourceProcess);
20763 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20765 sourceProcesses.put(sourceProcess, ass);
20769 if (ass.mNesting == 1) {
20770 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20771 ass.mLastState = sourceState;
20776 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20777 ComponentName targetComponent) {
20778 if (!mTrackingAssociations) {
20781 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20782 = mAssociations.get(targetUid);
20783 if (components == null) {
20786 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20787 if (sourceUids == null) {
20790 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20791 if (sourceProcesses == null) {
20794 Association ass = sourceProcesses.get(sourceProcess);
20795 if (ass == null || ass.mNesting <= 0) {
20799 if (ass.mNesting == 0) {
20800 long uptime = SystemClock.uptimeMillis();
20801 ass.mTime += uptime - ass.mStartTime;
20802 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20803 += uptime - ass.mLastStateUptime;
20804 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20808 private void noteUidProcessState(final int uid, final int state) {
20809 mBatteryStatsService.noteUidProcessState(uid, state);
20810 if (mTrackingAssociations) {
20811 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20812 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20813 = mAssociations.valueAt(i1);
20814 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20815 SparseArray<ArrayMap<String, Association>> sourceUids
20816 = targetComponents.valueAt(i2);
20817 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20818 if (sourceProcesses != null) {
20819 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20820 Association ass = sourceProcesses.valueAt(i4);
20821 if (ass.mNesting >= 1) {
20822 // currently associated
20823 long uptime = SystemClock.uptimeMillis();
20824 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20825 += uptime - ass.mLastStateUptime;
20826 ass.mLastState = state;
20827 ass.mLastStateUptime = uptime;
20836 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20837 boolean doingAll, long now) {
20838 if (mAdjSeq == app.adjSeq) {
20839 // This adjustment has already been computed.
20840 return app.curRawAdj;
20843 if (app.thread == null) {
20844 app.adjSeq = mAdjSeq;
20845 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20846 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20847 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20850 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20851 app.adjSource = null;
20852 app.adjTarget = null;
20854 app.cached = false;
20856 final int activitiesSize = app.activities.size();
20858 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20859 // The max adjustment doesn't allow this app to be anything
20860 // below foreground, so it is not worth doing work for it.
20861 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20862 app.adjType = "fixed";
20863 app.adjSeq = mAdjSeq;
20864 app.curRawAdj = app.maxAdj;
20865 app.foregroundActivities = false;
20866 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20867 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20868 // System processes can do UI, and when they do we want to have
20869 // them trim their memory after the user leaves the UI. To
20870 // facilitate this, here we need to determine whether or not it
20871 // is currently showing UI.
20872 app.systemNoUi = true;
20873 if (app == TOP_APP) {
20874 app.systemNoUi = false;
20875 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20876 app.adjType = "pers-top-activity";
20877 } else if (app.hasTopUi) {
20878 app.systemNoUi = false;
20879 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20880 app.adjType = "pers-top-ui";
20881 } else if (activitiesSize > 0) {
20882 for (int j = 0; j < activitiesSize; j++) {
20883 final ActivityRecord r = app.activities.get(j);
20885 app.systemNoUi = false;
20889 if (!app.systemNoUi) {
20890 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20892 return (app.curAdj=app.maxAdj);
20895 app.systemNoUi = false;
20897 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20899 // Determine the importance of the process, starting with most
20900 // important to least, and assign an appropriate OOM adjustment.
20904 boolean foregroundActivities = false;
20905 mTmpBroadcastQueue.clear();
20906 if (app == TOP_APP) {
20907 // The last app on the list is the foreground app.
20908 adj = ProcessList.FOREGROUND_APP_ADJ;
20909 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20910 app.adjType = "top-activity";
20911 foregroundActivities = true;
20912 procState = PROCESS_STATE_CUR_TOP;
20913 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20914 } else if (app.instr != null) {
20915 // Don't want to kill running instrumentation.
20916 adj = ProcessList.FOREGROUND_APP_ADJ;
20917 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20918 app.adjType = "instrumentation";
20919 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20920 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20921 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20922 // An app that is currently receiving a broadcast also
20923 // counts as being in the foreground for OOM killer purposes.
20924 // It's placed in a sched group based on the nature of the
20925 // broadcast as reflected by which queue it's active in.
20926 adj = ProcessList.FOREGROUND_APP_ADJ;
20927 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20928 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20929 app.adjType = "broadcast";
20930 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20931 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20932 } else if (app.executingServices.size() > 0) {
20933 // An app that is currently executing a service callback also
20934 // counts as being in the foreground.
20935 adj = ProcessList.FOREGROUND_APP_ADJ;
20936 schedGroup = app.execServicesFg ?
20937 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20938 app.adjType = "exec-service";
20939 procState = ActivityManager.PROCESS_STATE_SERVICE;
20940 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20941 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20943 // As far as we know the process is empty. We may change our mind later.
20944 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20945 // At this point we don't actually know the adjustment. Use the cached adj
20946 // value that the caller wants us to.
20948 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20951 app.adjType = "cch-empty";
20952 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20955 // Examine all activities if not already foreground.
20956 if (!foregroundActivities && activitiesSize > 0) {
20957 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20958 for (int j = 0; j < activitiesSize; j++) {
20959 final ActivityRecord r = app.activities.get(j);
20960 if (r.app != app) {
20961 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20962 + " instead of expected " + app);
20963 if (r.app == null || (r.app.uid == app.uid)) {
20964 // Only fix things up when they look sane
20971 // App has a visible activity; only upgrade adjustment.
20972 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20973 adj = ProcessList.VISIBLE_APP_ADJ;
20974 app.adjType = "vis-activity";
20975 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20977 if (procState > PROCESS_STATE_CUR_TOP) {
20978 procState = PROCESS_STATE_CUR_TOP;
20979 app.adjType = "vis-activity";
20980 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20982 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20983 app.cached = false;
20985 foregroundActivities = true;
20986 final TaskRecord task = r.getTask();
20987 if (task != null && minLayer > 0) {
20988 final int layer = task.mLayerRank;
20989 if (layer >= 0 && minLayer > layer) {
20994 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20995 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20996 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20997 app.adjType = "pause-activity";
20998 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21000 if (procState > PROCESS_STATE_CUR_TOP) {
21001 procState = PROCESS_STATE_CUR_TOP;
21002 app.adjType = "pause-activity";
21003 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21005 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21006 app.cached = false;
21008 foregroundActivities = true;
21009 } else if (r.state == ActivityState.STOPPING) {
21010 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21011 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21012 app.adjType = "stop-activity";
21013 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21015 // For the process state, we will at this point consider the
21016 // process to be cached. It will be cached either as an activity
21017 // or empty depending on whether the activity is finishing. We do
21018 // this so that we can treat the process as cached for purposes of
21019 // memory trimming (determing current memory level, trim command to
21020 // send to process) since there can be an arbitrary number of stopping
21021 // processes and they should soon all go into the cached state.
21022 if (!r.finishing) {
21023 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21024 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21025 app.adjType = "stop-activity";
21026 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21029 app.cached = false;
21031 foregroundActivities = true;
21033 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21034 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21035 app.adjType = "cch-act";
21036 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21040 if (adj == ProcessList.VISIBLE_APP_ADJ) {
21045 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21046 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21047 if (app.foregroundServices) {
21048 // The user is aware of this app, so make it visible.
21049 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21050 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21051 app.cached = false;
21052 app.adjType = "fg-service";
21053 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21054 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21055 } else if (app.hasOverlayUi) {
21056 // The process is display an overlay UI.
21057 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21058 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21059 app.cached = false;
21060 app.adjType = "has-overlay-ui";
21061 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21062 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21066 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21067 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21068 if (app.forcingToImportant != null) {
21069 // This is currently used for toasts... they are not interactive, and
21070 // we don't want them to cause the app to become fully foreground (and
21071 // thus out of background check), so we yes the best background level we can.
21072 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21073 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21074 app.cached = false;
21075 app.adjType = "force-imp";
21076 app.adjSource = app.forcingToImportant;
21077 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21078 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21082 if (app == mHeavyWeightProcess) {
21083 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21084 // We don't want to kill the current heavy-weight process.
21085 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21086 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21087 app.cached = false;
21088 app.adjType = "heavy";
21089 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21091 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21092 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21093 app.adjType = "heavy";
21094 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21098 if (app == mHomeProcess) {
21099 if (adj > ProcessList.HOME_APP_ADJ) {
21100 // This process is hosting what we currently consider to be the
21101 // home app, so we don't want to let it go into the background.
21102 adj = ProcessList.HOME_APP_ADJ;
21103 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21104 app.cached = false;
21105 app.adjType = "home";
21106 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21108 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21109 procState = ActivityManager.PROCESS_STATE_HOME;
21110 app.adjType = "home";
21111 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21115 if (app == mPreviousProcess && app.activities.size() > 0) {
21116 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21117 // This was the previous process that showed UI to the user.
21118 // We want to try to keep it around more aggressively, to give
21119 // a good experience around switching between two apps.
21120 adj = ProcessList.PREVIOUS_APP_ADJ;
21121 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21122 app.cached = false;
21123 app.adjType = "previous";
21124 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21126 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21127 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21128 app.adjType = "previous";
21129 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21133 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21134 + " reason=" + app.adjType);
21136 // By default, we use the computed adjustment. It may be changed if
21137 // there are applications dependent on our services or providers, but
21138 // this gives us a baseline and makes sure we don't get into an
21139 // infinite recursion.
21140 app.adjSeq = mAdjSeq;
21141 app.curRawAdj = adj;
21142 app.hasStartedServices = false;
21144 if (mBackupTarget != null && app == mBackupTarget.app) {
21145 // If possible we want to avoid killing apps while they're being backed up
21146 if (adj > ProcessList.BACKUP_APP_ADJ) {
21147 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21148 adj = ProcessList.BACKUP_APP_ADJ;
21149 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21150 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21152 app.adjType = "backup";
21153 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21154 app.cached = false;
21156 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21157 procState = ActivityManager.PROCESS_STATE_BACKUP;
21158 app.adjType = "backup";
21159 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21163 boolean mayBeTop = false;
21164 String mayBeTopType = null;
21165 Object mayBeTopSource = null;
21166 Object mayBeTopTarget = null;
21168 for (int is = app.services.size()-1;
21169 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21170 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21171 || procState > ActivityManager.PROCESS_STATE_TOP);
21173 ServiceRecord s = app.services.valueAt(is);
21174 if (s.startRequested) {
21175 app.hasStartedServices = true;
21176 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21177 procState = ActivityManager.PROCESS_STATE_SERVICE;
21178 app.adjType = "started-services";
21179 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21181 if (app.hasShownUi && app != mHomeProcess) {
21182 // If this process has shown some UI, let it immediately
21183 // go to the LRU list because it may be pretty heavy with
21184 // UI stuff. We'll tag it with a label just to help
21185 // debug and understand what is going on.
21186 if (adj > ProcessList.SERVICE_ADJ) {
21187 app.adjType = "cch-started-ui-services";
21190 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21191 // This service has seen some activity within
21192 // recent memory, so we will keep its process ahead
21193 // of the background processes.
21194 if (adj > ProcessList.SERVICE_ADJ) {
21195 adj = ProcessList.SERVICE_ADJ;
21196 app.adjType = "started-services";
21197 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21198 app.cached = false;
21201 // If we have let the service slide into the background
21202 // state, still have some text describing what it is doing
21203 // even though the service no longer has an impact.
21204 if (adj > ProcessList.SERVICE_ADJ) {
21205 app.adjType = "cch-started-services";
21210 for (int conni = s.connections.size()-1;
21211 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21212 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21213 || procState > ActivityManager.PROCESS_STATE_TOP);
21215 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21217 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21218 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21219 || procState > ActivityManager.PROCESS_STATE_TOP);
21221 // XXX should compute this based on the max of
21222 // all connected clients.
21223 ConnectionRecord cr = clist.get(i);
21224 if (cr.binding.client == app) {
21225 // Binding to ourself is not interesting.
21229 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21230 ProcessRecord client = cr.binding.client;
21231 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21232 TOP_APP, doingAll, now);
21233 int clientProcState = client.curProcState;
21234 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21235 // If the other app is cached for any reason, for purposes here
21236 // we are going to consider it empty. The specific cached state
21237 // doesn't propagate except under certain conditions.
21238 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21240 String adjType = null;
21241 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21242 // Not doing bind OOM management, so treat
21243 // this guy more like a started service.
21244 if (app.hasShownUi && app != mHomeProcess) {
21245 // If this process has shown some UI, let it immediately
21246 // go to the LRU list because it may be pretty heavy with
21247 // UI stuff. We'll tag it with a label just to help
21248 // debug and understand what is going on.
21249 if (adj > clientAdj) {
21250 adjType = "cch-bound-ui-services";
21252 app.cached = false;
21254 clientProcState = procState;
21256 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21257 // This service has not seen activity within
21258 // recent memory, so allow it to drop to the
21259 // LRU list if there is no other reason to keep
21260 // it around. We'll also tag it with a label just
21261 // to help debug and undertand what is going on.
21262 if (adj > clientAdj) {
21263 adjType = "cch-bound-services";
21269 if (adj > clientAdj) {
21270 // If this process has recently shown UI, and
21271 // the process that is binding to it is less
21272 // important than being visible, then we don't
21273 // care about the binding as much as we care
21274 // about letting this process get into the LRU
21275 // list to be killed and restarted if needed for
21277 if (app.hasShownUi && app != mHomeProcess
21278 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21279 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21280 adjType = "cch-bound-ui-services";
21284 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21285 |Context.BIND_IMPORTANT)) != 0) {
21286 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21287 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21288 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21289 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21290 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21291 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21292 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21293 newAdj = clientAdj;
21295 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21296 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21301 if (!client.cached) {
21302 app.cached = false;
21304 if (adj > newAdj) {
21306 adjType = "service";
21310 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21311 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21312 // This will treat important bound services identically to
21313 // the top app, which may behave differently than generic
21314 // foreground work.
21315 if (client.curSchedGroup > schedGroup) {
21316 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21317 schedGroup = client.curSchedGroup;
21319 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21322 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21323 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21324 // Special handling of clients who are in the top state.
21325 // We *may* want to consider this process to be in the
21326 // top state as well, but only if there is not another
21327 // reason for it to be running. Being on the top is a
21328 // special state, meaning you are specifically running
21329 // for the current top app. If the process is already
21330 // running in the background for some other reason, it
21331 // is more important to continue considering it to be
21332 // in the background state.
21334 mayBeTopType = "service";
21335 mayBeTopSource = cr.binding.client;
21336 mayBeTopTarget = s.name;
21337 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21339 // Special handling for above-top states (persistent
21340 // processes). These should not bring the current process
21341 // into the top state, since they are not on top. Instead
21342 // give them the best state after that.
21343 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21345 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21346 } else if (mWakefulness
21347 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21348 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21351 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21354 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21358 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21359 if (clientProcState <
21360 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21362 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21365 if (clientProcState <
21366 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21368 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21371 if (procState > clientProcState) {
21372 procState = clientProcState;
21373 if (adjType == null) {
21374 adjType = "service";
21377 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21378 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21379 app.pendingUiClean = true;
21381 if (adjType != null) {
21382 app.adjType = adjType;
21383 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21384 .REASON_SERVICE_IN_USE;
21385 app.adjSource = cr.binding.client;
21386 app.adjSourceProcState = clientProcState;
21387 app.adjTarget = s.name;
21388 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21389 + ": " + app + ", due to " + cr.binding.client
21390 + " adj=" + adj + " procState=" + procState);
21393 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21394 app.treatLikeActivity = true;
21396 final ActivityRecord a = cr.activity;
21397 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21398 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21399 (a.visible || a.state == ActivityState.RESUMED ||
21400 a.state == ActivityState.PAUSING)) {
21401 adj = ProcessList.FOREGROUND_APP_ADJ;
21402 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21403 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21404 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21406 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21409 app.cached = false;
21410 app.adjType = "service";
21411 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21412 .REASON_SERVICE_IN_USE;
21414 app.adjSourceProcState = procState;
21415 app.adjTarget = s.name;
21416 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21424 for (int provi = app.pubProviders.size()-1;
21425 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21426 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21427 || procState > ActivityManager.PROCESS_STATE_TOP);
21429 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21430 for (int i = cpr.connections.size()-1;
21431 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21432 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21433 || procState > ActivityManager.PROCESS_STATE_TOP);
21435 ContentProviderConnection conn = cpr.connections.get(i);
21436 ProcessRecord client = conn.client;
21437 if (client == app) {
21438 // Being our own client is not interesting.
21441 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21442 int clientProcState = client.curProcState;
21443 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21444 // If the other app is cached for any reason, for purposes here
21445 // we are going to consider it empty.
21446 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21448 String adjType = null;
21449 if (adj > clientAdj) {
21450 if (app.hasShownUi && app != mHomeProcess
21451 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21452 adjType = "cch-ui-provider";
21454 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21455 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21456 adjType = "provider";
21458 app.cached &= client.cached;
21460 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21461 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21462 // Special handling of clients who are in the top state.
21463 // We *may* want to consider this process to be in the
21464 // top state as well, but only if there is not another
21465 // reason for it to be running. Being on the top is a
21466 // special state, meaning you are specifically running
21467 // for the current top app. If the process is already
21468 // running in the background for some other reason, it
21469 // is more important to continue considering it to be
21470 // in the background state.
21472 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21473 mayBeTopType = adjType = "provider-top";
21474 mayBeTopSource = client;
21475 mayBeTopTarget = cpr.name;
21477 // Special handling for above-top states (persistent
21478 // processes). These should not bring the current process
21479 // into the top state, since they are not on top. Instead
21480 // give them the best state after that.
21482 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21483 if (adjType == null) {
21484 adjType = "provider";
21488 if (procState > clientProcState) {
21489 procState = clientProcState;
21491 if (client.curSchedGroup > schedGroup) {
21492 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21494 if (adjType != null) {
21495 app.adjType = adjType;
21496 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21497 .REASON_PROVIDER_IN_USE;
21498 app.adjSource = client;
21499 app.adjSourceProcState = clientProcState;
21500 app.adjTarget = cpr.name;
21501 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21502 + ": " + app + ", due to " + client
21503 + " adj=" + adj + " procState=" + procState);
21506 // If the provider has external (non-framework) process
21507 // dependencies, ensure that its adjustment is at least
21508 // FOREGROUND_APP_ADJ.
21509 if (cpr.hasExternalProcessHandles()) {
21510 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21511 adj = ProcessList.FOREGROUND_APP_ADJ;
21512 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21513 app.cached = false;
21514 app.adjType = "ext-provider";
21515 app.adjTarget = cpr.name;
21516 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21518 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21519 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21524 if (app.lastProviderTime > 0 &&
21525 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21526 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21527 adj = ProcessList.PREVIOUS_APP_ADJ;
21528 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21529 app.cached = false;
21530 app.adjType = "recent-provider";
21531 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21533 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21534 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21535 app.adjType = "recent-provider";
21536 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21540 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21541 // A client of one of our services or providers is in the top state. We
21542 // *may* want to be in the top state, but not if we are already running in
21543 // the background for some other reason. For the decision here, we are going
21544 // to pick out a few specific states that we want to remain in when a client
21545 // is top (states that tend to be longer-term) and otherwise allow it to go
21546 // to the top state.
21547 switch (procState) {
21548 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21549 // Something else is keeping it at this level, just leave it.
21551 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21552 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21553 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21554 case ActivityManager.PROCESS_STATE_SERVICE:
21555 // These all are longer-term states, so pull them up to the top
21556 // of the background states, but not all the way to the top state.
21557 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21558 app.adjType = mayBeTopType;
21559 app.adjSource = mayBeTopSource;
21560 app.adjTarget = mayBeTopTarget;
21561 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21562 + ": " + app + ", due to " + mayBeTopSource
21563 + " adj=" + adj + " procState=" + procState);
21566 // Otherwise, top is a better choice, so take it.
21567 procState = ActivityManager.PROCESS_STATE_TOP;
21568 app.adjType = mayBeTopType;
21569 app.adjSource = mayBeTopSource;
21570 app.adjTarget = mayBeTopTarget;
21571 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21572 + ": " + app + ", due to " + mayBeTopSource
21573 + " adj=" + adj + " procState=" + procState);
21578 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21579 if (app.hasClientActivities) {
21580 // This is a cached process, but with client activities. Mark it so.
21581 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21582 app.adjType = "cch-client-act";
21583 } else if (app.treatLikeActivity) {
21584 // This is a cached process, but somebody wants us to treat it like it has
21585 // an activity, okay!
21586 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21587 app.adjType = "cch-as-act";
21591 if (adj == ProcessList.SERVICE_ADJ) {
21593 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21594 mNewNumServiceProcs++;
21595 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21596 if (!app.serviceb) {
21597 // This service isn't far enough down on the LRU list to
21598 // normally be a B service, but if we are low on RAM and it
21599 // is large we want to force it down since we would prefer to
21600 // keep launcher over it.
21601 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21602 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21603 app.serviceHighRam = true;
21604 app.serviceb = true;
21605 //Slog.i(TAG, "ADJ " + app + " high ram!");
21607 mNewNumAServiceProcs++;
21608 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21611 app.serviceHighRam = false;
21614 if (app.serviceb) {
21615 adj = ProcessList.SERVICE_B_ADJ;
21619 app.curRawAdj = adj;
21621 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21622 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21623 if (adj > app.maxAdj) {
21625 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21626 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21630 // Do final modification to adj. Everything we do between here and applying
21631 // the final setAdj must be done in this function, because we will also use
21632 // it when computing the final cached adj later. Note that we don't need to
21633 // worry about this for max adj above, since max adj will always be used to
21634 // keep it out of the cached vaues.
21635 app.curAdj = app.modifyRawOomAdj(adj);
21636 app.curSchedGroup = schedGroup;
21637 app.curProcState = procState;
21638 app.foregroundActivities = foregroundActivities;
21640 return app.curRawAdj;
21644 * Record new PSS sample for a process.
21646 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21648 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21650 proc.lastPssTime = now;
21651 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21652 if (DEBUG_PSS) Slog.d(TAG_PSS,
21653 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21654 + " state=" + ProcessList.makeProcStateString(procState));
21655 if (proc.initialIdlePss == 0) {
21656 proc.initialIdlePss = pss;
21658 proc.lastPss = pss;
21659 proc.lastSwapPss = swapPss;
21660 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21661 proc.lastCachedPss = pss;
21662 proc.lastCachedSwapPss = swapPss;
21665 final SparseArray<Pair<Long, String>> watchUids
21666 = mMemWatchProcesses.getMap().get(proc.processName);
21668 if (watchUids != null) {
21669 Pair<Long, String> val = watchUids.get(proc.uid);
21671 val = watchUids.get(0);
21677 if (check != null) {
21678 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21679 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21680 if (!isDebuggable) {
21681 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21682 isDebuggable = true;
21685 if (isDebuggable) {
21686 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21687 final ProcessRecord myProc = proc;
21688 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21689 mMemWatchDumpProcName = proc.processName;
21690 mMemWatchDumpFile = heapdumpFile.toString();
21691 mMemWatchDumpPid = proc.pid;
21692 mMemWatchDumpUid = proc.uid;
21693 BackgroundThread.getHandler().post(new Runnable() {
21695 public void run() {
21696 revokeUriPermission(ActivityThread.currentActivityThread()
21697 .getApplicationThread(),
21698 null, DumpHeapActivity.JAVA_URI,
21699 Intent.FLAG_GRANT_READ_URI_PERMISSION
21700 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21701 UserHandle.myUserId());
21702 ParcelFileDescriptor fd = null;
21704 heapdumpFile.delete();
21705 fd = ParcelFileDescriptor.open(heapdumpFile,
21706 ParcelFileDescriptor.MODE_CREATE |
21707 ParcelFileDescriptor.MODE_TRUNCATE |
21708 ParcelFileDescriptor.MODE_WRITE_ONLY |
21709 ParcelFileDescriptor.MODE_APPEND);
21710 IApplicationThread thread = myProc.thread;
21711 if (thread != null) {
21713 if (DEBUG_PSS) Slog.d(TAG_PSS,
21714 "Requesting dump heap from "
21715 + myProc + " to " + heapdumpFile);
21716 thread.dumpHeap(/* managed= */ true,
21717 /* mallocInfo= */ false, /* runGc= */ false,
21718 heapdumpFile.toString(), fd);
21719 } catch (RemoteException e) {
21722 } catch (FileNotFoundException e) {
21723 e.printStackTrace();
21728 } catch (IOException e) {
21735 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21736 + ", but debugging not enabled");
21743 * Schedule PSS collection of a process.
21745 void requestPssLocked(ProcessRecord proc, int procState) {
21746 if (mPendingPssProcesses.contains(proc)) {
21749 if (mPendingPssProcesses.size() == 0) {
21750 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21752 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21753 proc.pssProcState = procState;
21754 mPendingPssProcesses.add(proc);
21758 * Schedule PSS collection of all processes.
21760 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21762 if (now < (mLastFullPssTime +
21763 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21764 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21768 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21769 mLastFullPssTime = now;
21770 mFullPssPending = true;
21771 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21772 mPendingPssProcesses.clear();
21773 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21774 ProcessRecord app = mLruProcesses.get(i);
21775 if (app.thread == null
21776 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21779 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21780 app.pssProcState = app.setProcState;
21781 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21782 mTestPssMode, isSleepingLocked(), now);
21783 mPendingPssProcesses.add(app);
21786 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21789 public void setTestPssMode(boolean enabled) {
21790 synchronized (this) {
21791 mTestPssMode = enabled;
21793 // Whenever we enable the mode, we want to take a snapshot all of current
21794 // process mem use.
21795 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21801 * Ask a given process to GC right now.
21803 final void performAppGcLocked(ProcessRecord app) {
21805 app.lastRequestedGc = SystemClock.uptimeMillis();
21806 if (app.thread != null) {
21807 if (app.reportLowMemory) {
21808 app.reportLowMemory = false;
21809 app.thread.scheduleLowMemory();
21811 app.thread.processInBackground();
21814 } catch (Exception e) {
21820 * Returns true if things are idle enough to perform GCs.
21822 private final boolean canGcNowLocked() {
21823 boolean processingBroadcasts = false;
21824 for (BroadcastQueue q : mBroadcastQueues) {
21825 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21826 processingBroadcasts = true;
21829 return !processingBroadcasts
21830 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21834 * Perform GCs on all processes that are waiting for it, but only
21835 * if things are idle.
21837 final void performAppGcsLocked() {
21838 final int N = mProcessesToGc.size();
21842 if (canGcNowLocked()) {
21843 while (mProcessesToGc.size() > 0) {
21844 ProcessRecord proc = mProcessesToGc.remove(0);
21845 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21846 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21847 <= SystemClock.uptimeMillis()) {
21848 // To avoid spamming the system, we will GC processes one
21849 // at a time, waiting a few seconds between each.
21850 performAppGcLocked(proc);
21851 scheduleAppGcsLocked();
21854 // It hasn't been long enough since we last GCed this
21855 // process... put it in the list to wait for its time.
21856 addProcessToGcListLocked(proc);
21862 scheduleAppGcsLocked();
21867 * If all looks good, perform GCs on all processes waiting for them.
21869 final void performAppGcsIfAppropriateLocked() {
21870 if (canGcNowLocked()) {
21871 performAppGcsLocked();
21874 // Still not idle, wait some more.
21875 scheduleAppGcsLocked();
21879 * Schedule the execution of all pending app GCs.
21881 final void scheduleAppGcsLocked() {
21882 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21884 if (mProcessesToGc.size() > 0) {
21885 // Schedule a GC for the time to the next process.
21886 ProcessRecord proc = mProcessesToGc.get(0);
21887 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21889 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21890 long now = SystemClock.uptimeMillis();
21891 if (when < (now+mConstants.GC_TIMEOUT)) {
21892 when = now + mConstants.GC_TIMEOUT;
21894 mHandler.sendMessageAtTime(msg, when);
21899 * Add a process to the array of processes waiting to be GCed. Keeps the
21900 * list in sorted order by the last GC time. The process can't already be
21903 final void addProcessToGcListLocked(ProcessRecord proc) {
21904 boolean added = false;
21905 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21906 if (mProcessesToGc.get(i).lastRequestedGc <
21907 proc.lastRequestedGc) {
21909 mProcessesToGc.add(i+1, proc);
21914 mProcessesToGc.add(0, proc);
21919 * Set up to ask a process to GC itself. This will either do it
21920 * immediately, or put it on the list of processes to gc the next
21921 * time things are idle.
21923 final void scheduleAppGcLocked(ProcessRecord app) {
21924 long now = SystemClock.uptimeMillis();
21925 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21928 if (!mProcessesToGc.contains(app)) {
21929 addProcessToGcListLocked(app);
21930 scheduleAppGcsLocked();
21934 final void checkExcessivePowerUsageLocked() {
21935 updateCpuStatsNow();
21937 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21938 boolean doCpuKills = true;
21939 if (mLastPowerCheckUptime == 0) {
21940 doCpuKills = false;
21942 final long curUptime = SystemClock.uptimeMillis();
21943 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21944 mLastPowerCheckUptime = curUptime;
21945 int i = mLruProcesses.size();
21948 ProcessRecord app = mLruProcesses.get(i);
21949 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21950 if (app.lastCpuTime <= 0) {
21953 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21955 StringBuilder sb = new StringBuilder(128);
21956 sb.append("CPU for ");
21957 app.toShortString(sb);
21958 sb.append(": over ");
21959 TimeUtils.formatDuration(uptimeSince, sb);
21960 sb.append(" used ");
21961 TimeUtils.formatDuration(cputimeUsed, sb);
21963 sb.append((cputimeUsed*100)/uptimeSince);
21965 Slog.i(TAG_POWER, sb.toString());
21967 // If the process has used too much CPU over the last duration, the
21968 // user probably doesn't want this, so kill!
21969 if (doCpuKills && uptimeSince > 0) {
21970 // What is the limit for this process?
21972 long checkDur = curUptime - app.whenUnimportant;
21973 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21974 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21975 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21976 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21977 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21978 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21979 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21981 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21983 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21984 synchronized (stats) {
21985 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21986 uptimeSince, cputimeUsed);
21988 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21989 + " dur=" + checkDur + " limit=" + cpuLimit, true);
21990 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21993 app.lastCpuTime = app.curCpuTime;
21998 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22000 boolean success = true;
22002 if (app.curRawAdj != app.setRawAdj) {
22003 app.setRawAdj = app.curRawAdj;
22008 if (app.curAdj != app.setAdj) {
22009 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22010 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22011 String msg = "Set " + app.pid + " " + app.processName + " adj "
22012 + app.curAdj + ": " + app.adjType;
22013 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22015 app.setAdj = app.curAdj;
22016 app.verifiedAdj = ProcessList.INVALID_ADJ;
22019 if (app.setSchedGroup != app.curSchedGroup) {
22020 int oldSchedGroup = app.setSchedGroup;
22021 app.setSchedGroup = app.curSchedGroup;
22022 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22023 String msg = "Setting sched group of " + app.processName
22024 + " to " + app.curSchedGroup;
22025 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22027 if (app.waitingToKill != null && app.curReceivers.isEmpty()
22028 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22029 app.kill(app.waitingToKill, true);
22033 switch (app.curSchedGroup) {
22034 case ProcessList.SCHED_GROUP_BACKGROUND:
22035 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22037 case ProcessList.SCHED_GROUP_TOP_APP:
22038 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22039 processGroup = THREAD_GROUP_TOP_APP;
22042 processGroup = THREAD_GROUP_DEFAULT;
22045 long oldId = Binder.clearCallingIdentity();
22047 setProcessGroup(app.pid, processGroup);
22048 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22049 // do nothing if we already switched to RT
22050 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22051 mVrController.onTopProcChangedLocked(app);
22052 if (mUseFifoUiScheduling) {
22053 // Switch UI pipeline for app to SCHED_FIFO
22054 app.savedPriority = Process.getThreadPriority(app.pid);
22055 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22056 if (app.renderThreadTid != 0) {
22057 scheduleAsFifoPriority(app.renderThreadTid,
22058 /* suppressLogs */true);
22059 if (DEBUG_OOM_ADJ) {
22060 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22061 app.renderThreadTid + ") to FIFO");
22064 if (DEBUG_OOM_ADJ) {
22065 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22069 // Boost priority for top app UI and render threads
22070 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22071 if (app.renderThreadTid != 0) {
22073 setThreadPriority(app.renderThreadTid,
22074 TOP_APP_PRIORITY_BOOST);
22075 } catch (IllegalArgumentException e) {
22076 // thread died, ignore
22081 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22082 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22083 mVrController.onTopProcChangedLocked(app);
22084 if (mUseFifoUiScheduling) {
22086 // Reset UI pipeline to SCHED_OTHER
22087 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22088 setThreadPriority(app.pid, app.savedPriority);
22089 if (app.renderThreadTid != 0) {
22090 setThreadScheduler(app.renderThreadTid,
22092 setThreadPriority(app.renderThreadTid, -4);
22094 } catch (IllegalArgumentException e) {
22096 "Failed to set scheduling policy, thread does not exist:\n"
22098 } catch (SecurityException e) {
22099 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22102 // Reset priority for top app UI and render threads
22103 setThreadPriority(app.pid, 0);
22104 if (app.renderThreadTid != 0) {
22105 setThreadPriority(app.renderThreadTid, 0);
22109 } catch (Exception e) {
22111 Slog.w(TAG, "Failed setting process group of " + app.pid
22112 + " to " + app.curSchedGroup);
22113 Slog.w(TAG, "at location", e);
22116 Binder.restoreCallingIdentity(oldId);
22120 if (app.repForegroundActivities != app.foregroundActivities) {
22121 app.repForegroundActivities = app.foregroundActivities;
22122 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22124 if (app.repProcState != app.curProcState) {
22125 app.repProcState = app.curProcState;
22126 if (app.thread != null) {
22129 //RuntimeException h = new RuntimeException("here");
22130 Slog.i(TAG, "Sending new process state " + app.repProcState
22131 + " to " + app /*, h*/);
22133 app.thread.setProcessState(app.repProcState);
22134 } catch (RemoteException e) {
22138 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22139 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22140 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22141 // Experimental code to more aggressively collect pss while
22142 // running test... the problem is that this tends to collect
22143 // the data right when a process is transitioning between process
22144 // states, which well tend to give noisy data.
22145 long start = SystemClock.uptimeMillis();
22146 long pss = Debug.getPss(app.pid, mTmpLong, null);
22147 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22148 mPendingPssProcesses.remove(app);
22149 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22150 + " to " + app.curProcState + ": "
22151 + (SystemClock.uptimeMillis()-start) + "ms");
22153 app.lastStateTime = now;
22154 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22155 mTestPssMode, isSleepingLocked(), now);
22156 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22157 + ProcessList.makeProcStateString(app.setProcState) + " to "
22158 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22159 + (app.nextPssTime-now) + ": " + app);
22161 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22162 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22164 requestPssLocked(app, app.setProcState);
22165 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22166 mTestPssMode, isSleepingLocked(), now);
22167 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22168 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22170 if (app.setProcState != app.curProcState) {
22171 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22172 String msg = "Proc state change of " + app.processName
22173 + " to " + app.curProcState;
22174 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22176 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22177 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22178 if (setImportant && !curImportant) {
22179 // This app is no longer something we consider important enough to allow to
22180 // use arbitrary amounts of battery power. Note
22181 // its current CPU time to later know to kill it if
22182 // it is not behaving well.
22183 app.whenUnimportant = now;
22184 app.lastCpuTime = 0;
22186 // Inform UsageStats of important process state change
22187 // Must be called before updating setProcState
22188 maybeUpdateUsageStatsLocked(app, nowElapsed);
22190 app.setProcState = app.curProcState;
22191 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22192 app.notCachedSinceIdle = false;
22195 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22197 app.procStateChanged = true;
22199 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22200 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22201 // For apps that sit around for a long time in the interactive state, we need
22202 // to report this at least once a day so they don't go idle.
22203 maybeUpdateUsageStatsLocked(app, nowElapsed);
22206 if (changes != 0) {
22207 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22208 "Changes in " + app + ": " + changes);
22209 int i = mPendingProcessChanges.size()-1;
22210 ProcessChangeItem item = null;
22212 item = mPendingProcessChanges.get(i);
22213 if (item.pid == app.pid) {
22214 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22215 "Re-using existing item: " + item);
22221 // No existing item in pending changes; need a new one.
22222 final int NA = mAvailProcessChanges.size();
22224 item = mAvailProcessChanges.remove(NA-1);
22225 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22226 "Retrieving available item: " + item);
22228 item = new ProcessChangeItem();
22229 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22230 "Allocating new item: " + item);
22233 item.pid = app.pid;
22234 item.uid = app.info.uid;
22235 if (mPendingProcessChanges.size() == 0) {
22236 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22237 "*** Enqueueing dispatch processes changed!");
22238 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22240 mPendingProcessChanges.add(item);
22242 item.changes |= changes;
22243 item.foregroundActivities = app.repForegroundActivities;
22244 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22245 "Item " + Integer.toHexString(System.identityHashCode(item))
22246 + " " + app.toShortString() + ": changes=" + item.changes
22247 + " foreground=" + item.foregroundActivities
22248 + " type=" + app.adjType + " source=" + app.adjSource
22249 + " target=" + app.adjTarget);
22255 private boolean isEphemeralLocked(int uid) {
22256 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22257 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22260 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22265 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22266 final UidRecord.ChangeItem pendingChange;
22267 if (uidRec == null || uidRec.pendingChange == null) {
22268 if (mPendingUidChanges.size() == 0) {
22269 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22270 "*** Enqueueing dispatch uid changed!");
22271 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22273 final int NA = mAvailUidChanges.size();
22275 pendingChange = mAvailUidChanges.remove(NA-1);
22276 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22277 "Retrieving available item: " + pendingChange);
22279 pendingChange = new UidRecord.ChangeItem();
22280 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22281 "Allocating new item: " + pendingChange);
22283 if (uidRec != null) {
22284 uidRec.pendingChange = pendingChange;
22285 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22286 // If this uid is going away, and we haven't yet reported it is gone,
22288 change |= UidRecord.CHANGE_IDLE;
22290 } else if (uid < 0) {
22291 throw new IllegalArgumentException("No UidRecord or uid");
22293 pendingChange.uidRecord = uidRec;
22294 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22295 mPendingUidChanges.add(pendingChange);
22297 pendingChange = uidRec.pendingChange;
22298 // If there is no change in idle or active state, then keep whatever was pending.
22299 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22300 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22301 | UidRecord.CHANGE_ACTIVE));
22303 // If there is no change in cached or uncached state, then keep whatever was pending.
22304 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22305 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22306 | UidRecord.CHANGE_UNCACHED));
22308 // If this is a report of the UID being gone, then we shouldn't keep any previous
22309 // report of it being active or cached. (That is, a gone uid is never active,
22310 // and never cached.)
22311 if ((change & UidRecord.CHANGE_GONE) != 0) {
22312 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22313 if (!uidRec.idle) {
22314 // If this uid is going away, and we haven't yet reported it is gone,
22316 change |= UidRecord.CHANGE_IDLE;
22320 pendingChange.change = change;
22321 pendingChange.processState = uidRec != null
22322 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22323 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22324 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22325 if (uidRec != null) {
22326 uidRec.lastReportedChange = change;
22327 uidRec.updateLastDispatchedProcStateSeq(change);
22330 // Directly update the power manager, since we sit on top of it and it is critical
22331 // it be kept in sync (so wake locks will be held as soon as appropriate).
22332 if (mLocalPowerManager != null) {
22333 // TO DO: dispatch cached/uncached changes here, so we don't need to report
22334 // all proc state changes.
22335 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22336 mLocalPowerManager.uidActive(pendingChange.uid);
22338 if ((change & UidRecord.CHANGE_IDLE) != 0) {
22339 mLocalPowerManager.uidIdle(pendingChange.uid);
22341 if ((change & UidRecord.CHANGE_GONE) != 0) {
22342 mLocalPowerManager.uidGone(pendingChange.uid);
22344 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22345 pendingChange.processState);
22350 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22351 String authority) {
22352 if (app == null) return;
22353 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22354 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22355 if (userState == null) return;
22356 final long now = SystemClock.elapsedRealtime();
22357 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22358 if (lastReported == null || lastReported < now - 60 * 1000L) {
22359 if (mSystemReady) {
22360 // Cannot touch the user stats if not system ready
22361 mUsageStatsService.reportContentProviderUsage(
22362 authority, providerPkgName, app.userId);
22364 userState.mProviderLastReportedFg.put(authority, now);
22369 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22370 if (DEBUG_USAGE_STATS) {
22371 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22372 + "] state changes: old = " + app.setProcState + ", new = "
22373 + app.curProcState);
22375 if (mUsageStatsService == null) {
22378 boolean isInteraction;
22379 // To avoid some abuse patterns, we are going to be careful about what we consider
22380 // to be an app interaction. Being the top activity doesn't count while the display
22381 // is sleeping, nor do short foreground services.
22382 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22383 isInteraction = true;
22384 app.fgInteractionTime = 0;
22385 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22386 if (app.fgInteractionTime == 0) {
22387 app.fgInteractionTime = nowElapsed;
22388 isInteraction = false;
22390 isInteraction = nowElapsed > app.fgInteractionTime
22391 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22394 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22395 app.fgInteractionTime = 0;
22397 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22398 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22399 app.interactionEventTime = nowElapsed;
22400 String[] packages = app.getPackageList();
22401 if (packages != null) {
22402 for (int i = 0; i < packages.length; i++) {
22403 mUsageStatsService.reportEvent(packages[i], app.userId,
22404 UsageEvents.Event.SYSTEM_INTERACTION);
22408 app.reportedInteraction = isInteraction;
22409 if (!isInteraction) {
22410 app.interactionEventTime = 0;
22414 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22415 if (proc.thread != null) {
22416 if (proc.baseProcessTracker != null) {
22417 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22422 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22423 ProcessRecord TOP_APP, boolean doingAll, long now) {
22424 if (app.thread == null) {
22428 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22430 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22433 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22435 if (isForeground != proc.foregroundServices) {
22436 proc.foregroundServices = isForeground;
22437 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22439 if (isForeground) {
22440 if (curProcs == null) {
22441 curProcs = new ArrayList<ProcessRecord>();
22442 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22444 if (!curProcs.contains(proc)) {
22445 curProcs.add(proc);
22446 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22447 proc.info.packageName, proc.info.uid);
22450 if (curProcs != null) {
22451 if (curProcs.remove(proc)) {
22452 mBatteryStatsService.noteEvent(
22453 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22454 proc.info.packageName, proc.info.uid);
22455 if (curProcs.size() <= 0) {
22456 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22462 updateOomAdjLocked();
22467 private final ActivityRecord resumedAppLocked() {
22468 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22472 pkg = act.packageName;
22473 uid = act.info.applicationInfo.uid;
22478 // Has the UID or resumed package name changed?
22479 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22480 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22481 if (mCurResumedPackage != null) {
22482 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22483 mCurResumedPackage, mCurResumedUid);
22485 mCurResumedPackage = pkg;
22486 mCurResumedUid = uid;
22487 if (mCurResumedPackage != null) {
22488 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22489 mCurResumedPackage, mCurResumedUid);
22496 * Update OomAdj for a specific process.
22497 * @param app The process to update
22498 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22499 * if necessary, or skip.
22500 * @return whether updateOomAdjLocked(app) was successful.
22502 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22503 final ActivityRecord TOP_ACT = resumedAppLocked();
22504 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22505 final boolean wasCached = app.cached;
22509 // This is the desired cached adjusment we want to tell it to use.
22510 // If our app is currently cached, we know it, and that is it. Otherwise,
22511 // we don't know it yet, and it needs to now be cached we will then
22512 // need to do a complete oom adj.
22513 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22514 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22515 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22516 SystemClock.uptimeMillis());
22518 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22519 // Changed to/from cached state, so apps after it in the LRU
22520 // list may also be changed.
22521 updateOomAdjLocked();
22526 final void updateOomAdjLocked() {
22527 final ActivityRecord TOP_ACT = resumedAppLocked();
22528 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22529 final long now = SystemClock.uptimeMillis();
22530 final long nowElapsed = SystemClock.elapsedRealtime();
22531 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22532 final int N = mLruProcesses.size();
22535 RuntimeException e = new RuntimeException();
22536 e.fillInStackTrace();
22537 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22540 // Reset state in all uid records.
22541 for (int i=mActiveUids.size()-1; i>=0; i--) {
22542 final UidRecord uidRec = mActiveUids.valueAt(i);
22543 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22544 "Starting update of " + uidRec);
22548 mStackSupervisor.rankTaskLayersIfNeeded();
22551 mNewNumServiceProcs = 0;
22552 mNewNumAServiceProcs = 0;
22554 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22555 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22557 // Let's determine how many processes we have running vs.
22558 // how many slots we have for background processes; we may want
22559 // to put multiple processes in a slot of there are enough of
22561 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22562 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22563 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22564 if (numEmptyProcs > cachedProcessLimit) {
22565 // If there are more empty processes than our limit on cached
22566 // processes, then use the cached process limit for the factor.
22567 // This ensures that the really old empty processes get pushed
22568 // down to the bottom, so if we are running low on memory we will
22569 // have a better chance at keeping around more cached processes
22570 // instead of a gazillion empty processes.
22571 numEmptyProcs = cachedProcessLimit;
22573 int emptyFactor = numEmptyProcs/numSlots;
22574 if (emptyFactor < 1) emptyFactor = 1;
22575 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22576 if (cachedFactor < 1) cachedFactor = 1;
22577 int stepCached = 0;
22581 int numTrimming = 0;
22583 mNumNonCachedProcs = 0;
22584 mNumCachedHiddenProcs = 0;
22586 // First update the OOM adjustment for each of the
22587 // application processes based on their current state.
22588 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22589 int nextCachedAdj = curCachedAdj+1;
22590 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22591 int nextEmptyAdj = curEmptyAdj+2;
22592 for (int i=N-1; i>=0; i--) {
22593 ProcessRecord app = mLruProcesses.get(i);
22594 if (!app.killedByAm && app.thread != null) {
22595 app.procStateChanged = false;
22596 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22598 // If we haven't yet assigned the final cached adj
22599 // to the process, do that now.
22600 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22601 switch (app.curProcState) {
22602 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22603 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22604 // This process is a cached process holding activities...
22605 // assign it the next cached value for that type, and then
22606 // step that cached level.
22607 app.curRawAdj = curCachedAdj;
22608 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22609 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22610 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22612 if (curCachedAdj != nextCachedAdj) {
22614 if (stepCached >= cachedFactor) {
22616 curCachedAdj = nextCachedAdj;
22617 nextCachedAdj += 2;
22618 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22619 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22625 // For everything else, assign next empty cached process
22626 // level and bump that up. Note that this means that
22627 // long-running services that have dropped down to the
22628 // cached level will be treated as empty (since their process
22629 // state is still as a service), which is what we want.
22630 app.curRawAdj = curEmptyAdj;
22631 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22632 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22633 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22635 if (curEmptyAdj != nextEmptyAdj) {
22637 if (stepEmpty >= emptyFactor) {
22639 curEmptyAdj = nextEmptyAdj;
22641 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22642 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22650 applyOomAdjLocked(app, true, now, nowElapsed);
22652 // Count the number of process types.
22653 switch (app.curProcState) {
22654 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22655 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22656 mNumCachedHiddenProcs++;
22658 if (numCached > cachedProcessLimit) {
22659 app.kill("cached #" + numCached, true);
22662 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22663 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22664 && app.lastActivityTime < oldTime) {
22665 app.kill("empty for "
22666 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22667 / 1000) + "s", true);
22670 if (numEmpty > emptyProcessLimit) {
22671 app.kill("empty #" + numEmpty, true);
22676 mNumNonCachedProcs++;
22680 if (app.isolated && app.services.size() <= 0) {
22681 // If this is an isolated process, and there are no
22682 // services running in it, then the process is no longer
22683 // needed. We agressively kill these because we can by
22684 // definition not re-use the same process again, and it is
22685 // good to avoid having whatever code was running in them
22686 // left sitting around after no longer needed.
22687 app.kill("isolated not needed", true);
22689 // Keeping this process, update its uid.
22690 final UidRecord uidRec = app.uidRecord;
22691 if (uidRec != null) {
22692 uidRec.ephemeral = app.info.isInstantApp();
22693 if (uidRec.curProcState > app.curProcState) {
22694 uidRec.curProcState = app.curProcState;
22696 if (app.foregroundServices) {
22697 uidRec.foregroundServices = true;
22702 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22703 && !app.killedByAm) {
22709 incrementProcStateSeqAndNotifyAppsLocked();
22711 mNumServiceProcs = mNewNumServiceProcs;
22713 // Now determine the memory trimming level of background processes.
22714 // Unfortunately we need to start at the back of the list to do this
22715 // properly. We only do this if the number of background apps we
22716 // are managing to keep around is less than half the maximum we desire;
22717 // if we are keeping a good number around, we'll let them use whatever
22718 // memory they want.
22719 final int numCachedAndEmpty = numCached + numEmpty;
22721 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22722 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22723 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22724 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22725 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22726 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22728 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22731 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22733 // We always allow the memory level to go up (better). We only allow it to go
22734 // down if we are in a state where that is allowed, *and* the total number of processes
22735 // has gone down since last time.
22736 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22737 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22738 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22739 if (memFactor > mLastMemoryLevel) {
22740 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22741 memFactor = mLastMemoryLevel;
22742 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22745 if (memFactor != mLastMemoryLevel) {
22746 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22748 mLastMemoryLevel = memFactor;
22749 mLastNumProcesses = mLruProcesses.size();
22750 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22751 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22752 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22753 if (mLowRamStartTime == 0) {
22754 mLowRamStartTime = now;
22758 switch (memFactor) {
22759 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22760 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22762 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22763 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22766 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22769 int factor = numTrimming/3;
22771 if (mHomeProcess != null) minFactor++;
22772 if (mPreviousProcess != null) minFactor++;
22773 if (factor < minFactor) factor = minFactor;
22774 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22775 for (int i=N-1; i>=0; i--) {
22776 ProcessRecord app = mLruProcesses.get(i);
22777 if (allChanged || app.procStateChanged) {
22778 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22779 app.procStateChanged = false;
22781 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22782 && !app.killedByAm) {
22783 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22785 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22786 "Trimming memory of " + app.processName + " to " + curLevel);
22787 app.thread.scheduleTrimMemory(curLevel);
22788 } catch (RemoteException e) {
22791 // For now we won't do this; our memory trimming seems
22792 // to be good enough at this point that destroying
22793 // activities causes more harm than good.
22794 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22795 && app != mHomeProcess && app != mPreviousProcess) {
22796 // Need to do this on its own message because the stack may not
22797 // be in a consistent state at this point.
22798 // For these apps we will also finish their activities
22799 // to help them free memory.
22800 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22804 app.trimMemoryLevel = curLevel;
22806 if (step >= factor) {
22808 switch (curLevel) {
22809 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22810 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22812 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22813 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22817 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22818 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22819 && app.thread != null) {
22821 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22822 "Trimming memory of heavy-weight " + app.processName
22823 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22824 app.thread.scheduleTrimMemory(
22825 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22826 } catch (RemoteException e) {
22829 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22831 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22832 || app.systemNoUi) && app.pendingUiClean) {
22833 // If this application is now in the background and it
22834 // had done UI, then give it the special trim level to
22835 // have it free UI resources.
22836 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22837 if (app.trimMemoryLevel < level && app.thread != null) {
22839 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22840 "Trimming memory of bg-ui " + app.processName
22842 app.thread.scheduleTrimMemory(level);
22843 } catch (RemoteException e) {
22846 app.pendingUiClean = false;
22848 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22850 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22851 "Trimming memory of fg " + app.processName
22852 + " to " + fgTrimLevel);
22853 app.thread.scheduleTrimMemory(fgTrimLevel);
22854 } catch (RemoteException e) {
22857 app.trimMemoryLevel = fgTrimLevel;
22861 if (mLowRamStartTime != 0) {
22862 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22863 mLowRamStartTime = 0;
22865 for (int i=N-1; i>=0; i--) {
22866 ProcessRecord app = mLruProcesses.get(i);
22867 if (allChanged || app.procStateChanged) {
22868 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22869 app.procStateChanged = false;
22871 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22872 || app.systemNoUi) && app.pendingUiClean) {
22873 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22874 && app.thread != null) {
22876 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22877 "Trimming memory of ui hidden " + app.processName
22878 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22879 app.thread.scheduleTrimMemory(
22880 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22881 } catch (RemoteException e) {
22884 app.pendingUiClean = false;
22886 app.trimMemoryLevel = 0;
22890 if (mAlwaysFinishActivities) {
22891 // Need to do this on its own message because the stack may not
22892 // be in a consistent state at this point.
22893 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22897 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22900 ArrayList<UidRecord> becameIdle = null;
22902 // Update from any uid changes.
22903 if (mLocalPowerManager != null) {
22904 mLocalPowerManager.startUidChanges();
22906 for (int i=mActiveUids.size()-1; i>=0; i--) {
22907 final UidRecord uidRec = mActiveUids.valueAt(i);
22908 int uidChange = UidRecord.CHANGE_PROCSTATE;
22909 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22910 && (uidRec.setProcState != uidRec.curProcState
22911 || uidRec.setWhitelist != uidRec.curWhitelist)) {
22912 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22913 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22914 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22915 + " to " + uidRec.curWhitelist);
22916 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22917 && !uidRec.curWhitelist) {
22918 // UID is now in the background (and not on the temp whitelist). Was it
22919 // previously in the foreground (or on the temp whitelist)?
22920 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22921 || uidRec.setWhitelist) {
22922 uidRec.lastBackgroundTime = nowElapsed;
22923 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22924 // Note: the background settle time is in elapsed realtime, while
22925 // the handler time base is uptime. All this means is that we may
22926 // stop background uids later than we had intended, but that only
22927 // happens because the device was sleeping so we are okay anyway.
22928 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22929 mConstants.BACKGROUND_SETTLE_TIME);
22932 if (uidRec.idle && !uidRec.setIdle) {
22933 uidChange = UidRecord.CHANGE_IDLE;
22934 if (becameIdle == null) {
22935 becameIdle = new ArrayList<>();
22937 becameIdle.add(uidRec);
22941 uidChange = UidRecord.CHANGE_ACTIVE;
22942 EventLogTags.writeAmUidActive(uidRec.uid);
22943 uidRec.idle = false;
22945 uidRec.lastBackgroundTime = 0;
22947 final boolean wasCached = uidRec.setProcState
22948 > ActivityManager.PROCESS_STATE_RECEIVER;
22949 final boolean isCached = uidRec.curProcState
22950 > ActivityManager.PROCESS_STATE_RECEIVER;
22951 if (wasCached != isCached ||
22952 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22953 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22955 uidRec.setProcState = uidRec.curProcState;
22956 uidRec.setWhitelist = uidRec.curWhitelist;
22957 uidRec.setIdle = uidRec.idle;
22958 enqueueUidChangeLocked(uidRec, -1, uidChange);
22959 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22960 if (uidRec.foregroundServices) {
22961 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22965 if (mLocalPowerManager != null) {
22966 mLocalPowerManager.finishUidChanges();
22969 if (becameIdle != null) {
22970 // If we have any new uids that became idle this time, we need to make sure
22971 // they aren't left with running services.
22972 for (int i = becameIdle.size() - 1; i >= 0; i--) {
22973 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22977 if (mProcessStats.shouldWriteNowLocked(now)) {
22978 mHandler.post(new Runnable() {
22979 @Override public void run() {
22980 synchronized (ActivityManagerService.this) {
22981 mProcessStats.writeStateAsyncLocked();
22987 if (DEBUG_OOM_ADJ) {
22988 final long duration = SystemClock.uptimeMillis() - now;
22990 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22991 new RuntimeException("here").fillInStackTrace());
22993 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22999 public void makePackageIdle(String packageName, int userId) {
23000 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23001 != PackageManager.PERMISSION_GRANTED) {
23002 String msg = "Permission Denial: makePackageIdle() from pid="
23003 + Binder.getCallingPid()
23004 + ", uid=" + Binder.getCallingUid()
23005 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23007 throw new SecurityException(msg);
23009 final int callingPid = Binder.getCallingPid();
23010 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23011 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23012 long callingId = Binder.clearCallingIdentity();
23013 synchronized(this) {
23015 IPackageManager pm = AppGlobals.getPackageManager();
23018 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23019 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23020 } catch (RemoteException e) {
23022 if (pkgUid == -1) {
23023 throw new IllegalArgumentException("Unknown package name " + packageName);
23026 if (mLocalPowerManager != null) {
23027 mLocalPowerManager.startUidChanges();
23029 final int appId = UserHandle.getAppId(pkgUid);
23030 final int N = mActiveUids.size();
23031 for (int i=N-1; i>=0; i--) {
23032 final UidRecord uidRec = mActiveUids.valueAt(i);
23033 final long bgTime = uidRec.lastBackgroundTime;
23034 if (bgTime > 0 && !uidRec.idle) {
23035 if (UserHandle.getAppId(uidRec.uid) == appId) {
23036 if (userId == UserHandle.USER_ALL ||
23037 userId == UserHandle.getUserId(uidRec.uid)) {
23038 EventLogTags.writeAmUidIdle(uidRec.uid);
23039 uidRec.idle = true;
23040 uidRec.setIdle = true;
23041 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23042 + " from package " + packageName + " user " + userId);
23043 doStopUidLocked(uidRec.uid, uidRec);
23049 if (mLocalPowerManager != null) {
23050 mLocalPowerManager.finishUidChanges();
23052 Binder.restoreCallingIdentity(callingId);
23057 final void idleUids() {
23058 synchronized (this) {
23059 final int N = mActiveUids.size();
23063 final long nowElapsed = SystemClock.elapsedRealtime();
23064 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23066 if (mLocalPowerManager != null) {
23067 mLocalPowerManager.startUidChanges();
23069 for (int i=N-1; i>=0; i--) {
23070 final UidRecord uidRec = mActiveUids.valueAt(i);
23071 final long bgTime = uidRec.lastBackgroundTime;
23072 if (bgTime > 0 && !uidRec.idle) {
23073 if (bgTime <= maxBgTime) {
23074 EventLogTags.writeAmUidIdle(uidRec.uid);
23075 uidRec.idle = true;
23076 uidRec.setIdle = true;
23077 doStopUidLocked(uidRec.uid, uidRec);
23079 if (nextTime == 0 || nextTime > bgTime) {
23085 if (mLocalPowerManager != null) {
23086 mLocalPowerManager.finishUidChanges();
23088 if (nextTime > 0) {
23089 mHandler.removeMessages(IDLE_UIDS_MSG);
23090 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23091 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23097 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23098 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23099 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23103 void incrementProcStateSeqAndNotifyAppsLocked() {
23104 if (mWaitForNetworkTimeoutMs <= 0) {
23107 // Used for identifying which uids need to block for network.
23108 ArrayList<Integer> blockingUids = null;
23109 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23110 final UidRecord uidRec = mActiveUids.valueAt(i);
23111 // If the network is not restricted for uid, then nothing to do here.
23112 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23115 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23118 // If process state is not changed, then there's nothing to do.
23119 if (uidRec.setProcState == uidRec.curProcState) {
23122 final int blockState = getBlockStateForUid(uidRec);
23123 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23124 // there's nothing the app needs to do in this scenario.
23125 if (blockState == NETWORK_STATE_NO_CHANGE) {
23128 synchronized (uidRec.networkStateLock) {
23129 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23130 if (blockState == NETWORK_STATE_BLOCK) {
23131 if (blockingUids == null) {
23132 blockingUids = new ArrayList<>();
23134 blockingUids.add(uidRec.uid);
23136 if (DEBUG_NETWORK) {
23137 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23138 + " threads for uid: " + uidRec);
23140 if (uidRec.waitingForNetwork) {
23141 uidRec.networkStateLock.notifyAll();
23147 // There are no uids that need to block, so nothing more to do.
23148 if (blockingUids == null) {
23152 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23153 final ProcessRecord app = mLruProcesses.get(i);
23154 if (!blockingUids.contains(app.uid)) {
23157 if (!app.killedByAm && app.thread != null) {
23158 final UidRecord uidRec = mActiveUids.get(app.uid);
23160 if (DEBUG_NETWORK) {
23161 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23164 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23165 } catch (RemoteException ignored) {
23172 * Checks if the uid is coming from background to foreground or vice versa and returns
23173 * appropriate block state based on this.
23175 * @return blockState based on whether the uid is coming from background to foreground or
23176 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23177 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23178 * {@link #NETWORK_STATE_NO_CHANGE}.
23181 int getBlockStateForUid(UidRecord uidRec) {
23182 // Denotes whether uid's process state is currently allowed network access.
23183 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23184 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23185 // Denotes whether uid's process state was previously allowed network access.
23186 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23187 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23189 // When the uid is coming to foreground, AMS should inform the app thread that it should
23190 // block for the network rules to get updated before launching an activity.
23191 if (!wasAllowed && isAllowed) {
23192 return NETWORK_STATE_BLOCK;
23194 // When the uid is going to background, AMS should inform the app thread that if an
23195 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23196 if (wasAllowed && !isAllowed) {
23197 return NETWORK_STATE_UNBLOCK;
23199 return NETWORK_STATE_NO_CHANGE;
23202 final void runInBackgroundDisabled(int uid) {
23203 synchronized (this) {
23204 UidRecord uidRec = mActiveUids.get(uid);
23205 if (uidRec != null) {
23206 // This uid is actually running... should it be considered background now?
23208 doStopUidLocked(uidRec.uid, uidRec);
23211 // This uid isn't actually running... still send a report about it being "stopped".
23212 doStopUidLocked(uid, null);
23217 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23218 mServices.stopInBackgroundLocked(uid);
23219 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23223 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23225 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23226 long duration, String tag) {
23227 if (DEBUG_WHITELISTS) {
23228 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23229 + targetUid + ", " + duration + ")");
23232 synchronized (mPidsSelfLocked) {
23233 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23235 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23239 if (!pr.whitelistManager) {
23240 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23241 != PackageManager.PERMISSION_GRANTED) {
23242 if (DEBUG_WHITELISTS) {
23243 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23244 + ": pid " + callerPid + " is not allowed");
23251 tempWhitelistUidLocked(targetUid, duration, tag);
23255 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23257 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23258 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23259 setUidTempWhitelistStateLocked(targetUid, true);
23260 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23263 void pushTempWhitelist() {
23265 final PendingTempWhitelist[] list;
23267 // First copy out the pending changes... we need to leave them in the map for now,
23268 // in case someone needs to check what is coming up while we don't have the lock held.
23269 synchronized(this) {
23270 N = mPendingTempWhitelist.size();
23271 list = new PendingTempWhitelist[N];
23272 for (int i = 0; i < N; i++) {
23273 list[i] = mPendingTempWhitelist.valueAt(i);
23277 // Now safely dispatch changes to device idle controller.
23278 for (int i = 0; i < N; i++) {
23279 PendingTempWhitelist ptw = list[i];
23280 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23281 ptw.duration, true, ptw.tag);
23284 // And now we can safely remove them from the map.
23285 synchronized(this) {
23286 for (int i = 0; i < N; i++) {
23287 PendingTempWhitelist ptw = list[i];
23288 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23289 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23290 mPendingTempWhitelist.removeAt(index);
23296 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23297 boolean changed = false;
23298 for (int i=mActiveUids.size()-1; i>=0; i--) {
23299 final UidRecord uidRec = mActiveUids.valueAt(i);
23300 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23301 uidRec.curWhitelist = onWhitelist;
23306 updateOomAdjLocked();
23310 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23311 boolean changed = false;
23312 final UidRecord uidRec = mActiveUids.get(uid);
23313 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23314 uidRec.curWhitelist = onWhitelist;
23315 updateOomAdjLocked();
23319 final void trimApplications() {
23320 synchronized (this) {
23323 // First remove any unused application processes whose package
23324 // has been removed.
23325 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23326 final ProcessRecord app = mRemovedProcesses.get(i);
23327 if (app.activities.size() == 0
23328 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23330 TAG, "Exiting empty application process "
23331 + app.toShortString() + " ("
23332 + (app.thread != null ? app.thread.asBinder() : null)
23334 if (app.pid > 0 && app.pid != MY_PID) {
23335 app.kill("empty", false);
23338 app.thread.scheduleExit();
23339 } catch (Exception e) {
23340 // Ignore exceptions.
23343 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23344 mRemovedProcesses.remove(i);
23346 if (app.persistent) {
23347 addAppLocked(app.info, null, false, null /* ABI override */);
23352 // Now update the oom adj for all processes.
23353 updateOomAdjLocked();
23357 /** This method sends the specified signal to each of the persistent apps */
23358 public void signalPersistentProcesses(int sig) throws RemoteException {
23359 if (sig != SIGNAL_USR1) {
23360 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23363 synchronized (this) {
23364 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23365 != PackageManager.PERMISSION_GRANTED) {
23366 throw new SecurityException("Requires permission "
23367 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23370 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23371 ProcessRecord r = mLruProcesses.get(i);
23372 if (r.thread != null && r.persistent) {
23373 sendSignal(r.pid, sig);
23379 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23380 if (proc == null || proc == mProfileProc) {
23381 proc = mProfileProc;
23382 profileType = mProfileType;
23383 clearProfilerLocked();
23385 if (proc == null) {
23389 proc.thread.profilerControl(false, null, profileType);
23390 } catch (RemoteException e) {
23391 throw new IllegalStateException("Process disappeared");
23395 private void clearProfilerLocked() {
23396 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23398 mProfilerInfo.profileFd.close();
23399 } catch (IOException e) {
23402 mProfileApp = null;
23403 mProfileProc = null;
23404 mProfilerInfo = null;
23407 public boolean profileControl(String process, int userId, boolean start,
23408 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23411 synchronized (this) {
23412 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23413 // its own permission.
23414 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23415 != PackageManager.PERMISSION_GRANTED) {
23416 throw new SecurityException("Requires permission "
23417 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23420 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23421 throw new IllegalArgumentException("null profile info or fd");
23424 ProcessRecord proc = null;
23425 if (process != null) {
23426 proc = findProcessLocked(process, userId, "profileControl");
23429 if (start && (proc == null || proc.thread == null)) {
23430 throw new IllegalArgumentException("Unknown process: " + process);
23434 stopProfilerLocked(null, 0);
23435 setProfileApp(proc.info, proc.processName, profilerInfo);
23436 mProfileProc = proc;
23437 mProfileType = profileType;
23438 ParcelFileDescriptor fd = profilerInfo.profileFd;
23441 } catch (IOException e) {
23444 profilerInfo.profileFd = fd;
23445 proc.thread.profilerControl(start, profilerInfo, profileType);
23448 mProfilerInfo.profileFd.close();
23449 } catch (IOException e) {
23451 mProfilerInfo.profileFd = null;
23453 stopProfilerLocked(proc, profileType);
23454 if (profilerInfo != null && profilerInfo.profileFd != null) {
23456 profilerInfo.profileFd.close();
23457 } catch (IOException e) {
23464 } catch (RemoteException e) {
23465 throw new IllegalStateException("Process disappeared");
23467 if (profilerInfo != null && profilerInfo.profileFd != null) {
23469 profilerInfo.profileFd.close();
23470 } catch (IOException e) {
23476 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23477 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23478 userId, true, ALLOW_FULL_ONLY, callName, null);
23479 ProcessRecord proc = null;
23481 int pid = Integer.parseInt(process);
23482 synchronized (mPidsSelfLocked) {
23483 proc = mPidsSelfLocked.get(pid);
23485 } catch (NumberFormatException e) {
23488 if (proc == null) {
23489 ArrayMap<String, SparseArray<ProcessRecord>> all
23490 = mProcessNames.getMap();
23491 SparseArray<ProcessRecord> procs = all.get(process);
23492 if (procs != null && procs.size() > 0) {
23493 proc = procs.valueAt(0);
23494 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23495 for (int i=1; i<procs.size(); i++) {
23496 ProcessRecord thisProc = procs.valueAt(i);
23497 if (thisProc.userId == userId) {
23509 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23510 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23513 synchronized (this) {
23514 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23515 // its own permission (same as profileControl).
23516 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23517 != PackageManager.PERMISSION_GRANTED) {
23518 throw new SecurityException("Requires permission "
23519 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23523 throw new IllegalArgumentException("null fd");
23526 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23527 if (proc == null || proc.thread == null) {
23528 throw new IllegalArgumentException("Unknown process: " + process);
23531 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23532 if (!isDebuggable) {
23533 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23534 throw new SecurityException("Process not debuggable: " + proc);
23538 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23542 } catch (RemoteException e) {
23543 throw new IllegalStateException("Process disappeared");
23548 } catch (IOException e) {
23555 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23556 String reportPackage) {
23557 if (processName != null) {
23558 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23559 "setDumpHeapDebugLimit()");
23561 synchronized (mPidsSelfLocked) {
23562 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23563 if (proc == null) {
23564 throw new SecurityException("No process found for calling pid "
23565 + Binder.getCallingPid());
23567 if (!Build.IS_DEBUGGABLE
23568 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23569 throw new SecurityException("Not running a debuggable build");
23571 processName = proc.processName;
23573 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23574 throw new SecurityException("Package " + reportPackage + " is not running in "
23579 synchronized (this) {
23580 if (maxMemSize > 0) {
23581 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23584 mMemWatchProcesses.remove(processName, uid);
23586 mMemWatchProcesses.getMap().remove(processName);
23593 public void dumpHeapFinished(String path) {
23594 synchronized (this) {
23595 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23596 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23597 + " does not match last pid " + mMemWatchDumpPid);
23600 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23601 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23602 + " does not match last path " + mMemWatchDumpFile);
23605 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23606 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23608 // Forced gc to clean up the remnant hprof fd.
23609 Runtime.getRuntime().gc();
23613 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23614 public void monitor() {
23615 synchronized (this) { }
23618 void onCoreSettingsChange(Bundle settings) {
23619 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23620 ProcessRecord processRecord = mLruProcesses.get(i);
23622 if (processRecord.thread != null) {
23623 processRecord.thread.setCoreSettings(settings);
23625 } catch (RemoteException re) {
23631 // Multi-user methods
23634 * Start user, if its not already running, but don't bring it to foreground.
23637 public boolean startUserInBackground(final int userId) {
23638 return mUserController.startUser(userId, /* foreground */ false);
23642 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23643 return mUserController.unlockUser(userId, token, secret, listener);
23647 public boolean switchUser(final int targetUserId) {
23648 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23650 UserInfo targetUserInfo;
23651 synchronized (this) {
23652 currentUserId = mUserController.getCurrentUserIdLocked();
23653 targetUserInfo = mUserController.getUserInfo(targetUserId);
23654 if (targetUserId == currentUserId) {
23655 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23658 if (targetUserInfo == null) {
23659 Slog.w(TAG, "No user info for user #" + targetUserId);
23662 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23663 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23664 + " when device is in demo mode");
23667 if (!targetUserInfo.supportsSwitchTo()) {
23668 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23671 if (targetUserInfo.isManagedProfile()) {
23672 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23675 mUserController.setTargetUserIdLocked(targetUserId);
23677 if (mUserController.mUserSwitchUiEnabled) {
23678 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23679 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23680 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23681 mUiHandler.sendMessage(mHandler.obtainMessage(
23682 START_USER_SWITCH_UI_MSG, userNames));
23684 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23685 mHandler.sendMessage(mHandler.obtainMessage(
23686 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23691 void scheduleStartProfilesLocked() {
23692 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23693 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23694 DateUtils.SECOND_IN_MILLIS);
23699 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23700 return mUserController.stopUser(userId, force, callback);
23704 public UserInfo getCurrentUser() {
23705 return mUserController.getCurrentUser();
23708 String getStartedUserState(int userId) {
23709 synchronized (this) {
23710 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23711 return UserState.stateToString(userState.state);
23716 public boolean isUserRunning(int userId, int flags) {
23717 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23718 && checkCallingPermission(INTERACT_ACROSS_USERS)
23719 != PackageManager.PERMISSION_GRANTED) {
23720 String msg = "Permission Denial: isUserRunning() from pid="
23721 + Binder.getCallingPid()
23722 + ", uid=" + Binder.getCallingUid()
23723 + " requires " + INTERACT_ACROSS_USERS;
23725 throw new SecurityException(msg);
23727 synchronized (this) {
23728 return mUserController.isUserRunningLocked(userId, flags);
23733 public int[] getRunningUserIds() {
23734 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23735 != PackageManager.PERMISSION_GRANTED) {
23736 String msg = "Permission Denial: isUserRunning() from pid="
23737 + Binder.getCallingPid()
23738 + ", uid=" + Binder.getCallingUid()
23739 + " requires " + INTERACT_ACROSS_USERS;
23741 throw new SecurityException(msg);
23743 synchronized (this) {
23744 return mUserController.getStartedUserArrayLocked();
23749 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23750 mUserController.registerUserSwitchObserver(observer, name);
23754 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23755 mUserController.unregisterUserSwitchObserver(observer);
23758 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23759 if (info == null) return null;
23760 ApplicationInfo newInfo = new ApplicationInfo(info);
23761 newInfo.initForUser(userId);
23765 public boolean isUserStopped(int userId) {
23766 synchronized (this) {
23767 return mUserController.getStartedUserStateLocked(userId) == null;
23771 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23773 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23777 ActivityInfo info = new ActivityInfo(aInfo);
23778 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23782 private boolean processSanityChecksLocked(ProcessRecord process) {
23783 if (process == null || process.thread == null) {
23787 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23788 if (!isDebuggable) {
23789 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23797 public boolean startBinderTracking() throws RemoteException {
23798 synchronized (this) {
23799 mBinderTransactionTrackingEnabled = true;
23800 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23801 // permission (same as profileControl).
23802 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23803 != PackageManager.PERMISSION_GRANTED) {
23804 throw new SecurityException("Requires permission "
23805 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23808 for (int i = 0; i < mLruProcesses.size(); i++) {
23809 ProcessRecord process = mLruProcesses.get(i);
23810 if (!processSanityChecksLocked(process)) {
23814 process.thread.startBinderTracking();
23815 } catch (RemoteException e) {
23816 Log.v(TAG, "Process disappared");
23823 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23825 synchronized (this) {
23826 mBinderTransactionTrackingEnabled = false;
23827 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23828 // permission (same as profileControl).
23829 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23830 != PackageManager.PERMISSION_GRANTED) {
23831 throw new SecurityException("Requires permission "
23832 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23836 throw new IllegalArgumentException("null fd");
23839 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23840 pw.println("Binder transaction traces for all processes.\n");
23841 for (ProcessRecord process : mLruProcesses) {
23842 if (!processSanityChecksLocked(process)) {
23846 pw.println("Traces for process: " + process.processName);
23849 TransferPipe tp = new TransferPipe();
23851 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23852 tp.go(fd.getFileDescriptor());
23856 } catch (IOException e) {
23857 pw.println("Failure while dumping IPC traces from " + process +
23858 ". Exception: " + e);
23860 } catch (RemoteException e) {
23861 pw.println("Got a RemoteException while dumping IPC traces from " +
23862 process + ". Exception: " + e);
23873 } catch (IOException e) {
23880 final class LocalService extends ActivityManagerInternal {
23882 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23883 int targetUserId) {
23884 synchronized (ActivityManagerService.this) {
23885 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23886 targetPkg, intent, null, targetUserId);
23891 public String checkContentProviderAccess(String authority, int userId) {
23892 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23896 public void onWakefulnessChanged(int wakefulness) {
23897 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23901 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23902 String processName, String abiOverride, int uid, Runnable crashHandler) {
23903 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23904 processName, abiOverride, uid, crashHandler);
23908 public SleepToken acquireSleepToken(String tag, int displayId) {
23909 Preconditions.checkNotNull(tag);
23910 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23914 public ComponentName getHomeActivityForUser(int userId) {
23915 synchronized (ActivityManagerService.this) {
23916 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23917 return homeActivity == null ? null : homeActivity.realActivity;
23922 public void onUserRemoved(int userId) {
23923 synchronized (ActivityManagerService.this) {
23924 ActivityManagerService.this.onUserStoppedLocked(userId);
23926 mBatteryStatsService.onUserRemoved(userId);
23930 public void onLocalVoiceInteractionStarted(IBinder activity,
23931 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23932 synchronized (ActivityManagerService.this) {
23933 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23934 voiceSession, voiceInteractor);
23939 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23940 synchronized (ActivityManagerService.this) {
23941 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23942 reasons, timestamp);
23947 public void notifyAppTransitionFinished() {
23948 synchronized (ActivityManagerService.this) {
23949 mStackSupervisor.notifyAppTransitionDone();
23954 public void notifyAppTransitionCancelled() {
23955 synchronized (ActivityManagerService.this) {
23956 mStackSupervisor.notifyAppTransitionDone();
23961 public List<IBinder> getTopVisibleActivities() {
23962 synchronized (ActivityManagerService.this) {
23963 return mStackSupervisor.getTopVisibleActivities();
23968 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23969 synchronized (ActivityManagerService.this) {
23970 mStackSupervisor.setDockedStackMinimized(minimized);
23975 public void killForegroundAppsForUser(int userHandle) {
23976 synchronized (ActivityManagerService.this) {
23977 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23978 final int NP = mProcessNames.getMap().size();
23979 for (int ip = 0; ip < NP; ip++) {
23980 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23981 final int NA = apps.size();
23982 for (int ia = 0; ia < NA; ia++) {
23983 final ProcessRecord app = apps.valueAt(ia);
23984 if (app.persistent) {
23985 // We don't kill persistent processes.
23990 } else if (app.userId == userHandle && app.foregroundActivities) {
23991 app.removed = true;
23997 final int N = procs.size();
23998 for (int i = 0; i < N; i++) {
23999 removeProcessLocked(procs.get(i), false, true, "kill all fg");
24005 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24007 if (!(target instanceof PendingIntentRecord)) {
24008 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24011 synchronized (ActivityManagerService.this) {
24012 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24017 public void setDeviceIdleWhitelist(int[] appids) {
24018 synchronized (ActivityManagerService.this) {
24019 mDeviceIdleWhitelist = appids;
24024 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24025 synchronized (ActivityManagerService.this) {
24026 mDeviceIdleTempWhitelist = appids;
24027 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24032 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24034 Preconditions.checkNotNull(values, "Configuration must not be null");
24035 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24036 synchronized (ActivityManagerService.this) {
24037 updateConfigurationLocked(values, null, false, true, userId,
24038 false /* deferResume */);
24043 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24045 Preconditions.checkNotNull(intents, "intents");
24046 final String[] resolvedTypes = new String[intents.length];
24047 for (int i = 0; i < intents.length; i++) {
24048 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24051 // UID of the package on user userId.
24052 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24053 // packageUid may not be initialized.
24054 int packageUid = 0;
24056 packageUid = AppGlobals.getPackageManager().getPackageUid(
24057 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24058 } catch (RemoteException e) {
24059 // Shouldn't happen.
24062 synchronized (ActivityManagerService.this) {
24063 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24064 /*resultTo*/ null, bOptions, userId);
24069 public int getUidProcessState(int uid) {
24070 return getUidState(uid);
24074 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24075 synchronized (ActivityManagerService.this) {
24077 // We might change the visibilities here, so prepare an empty app transition which
24078 // might be overridden later if we actually change visibilities.
24079 final boolean wasTransitionSet =
24080 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24081 if (!wasTransitionSet) {
24082 mWindowManager.prepareAppTransition(TRANSIT_NONE,
24083 false /* alwaysKeepCurrent */);
24085 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24087 // If there was a transition set already we don't want to interfere with it as we
24088 // might be starting it too early.
24089 if (!wasTransitionSet) {
24090 mWindowManager.executeAppTransition();
24093 if (callback != null) {
24099 public boolean isSystemReady() {
24100 // no need to synchronize(this) just to read & return the value
24101 return mSystemReady;
24105 public void notifyKeyguardTrustedChanged() {
24106 synchronized (ActivityManagerService.this) {
24107 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24108 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24114 * Sets if the given pid has an overlay UI or not.
24116 * @param pid The pid we are setting overlay UI for.
24117 * @param hasOverlayUi True if the process has overlay UI.
24118 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24121 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24122 synchronized (ActivityManagerService.this) {
24123 final ProcessRecord pr;
24124 synchronized (mPidsSelfLocked) {
24125 pr = mPidsSelfLocked.get(pid);
24127 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24131 if (pr.hasOverlayUi == hasOverlayUi) {
24134 pr.hasOverlayUi = hasOverlayUi;
24135 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24136 updateOomAdjLocked(pr, true);
24141 * Called after the network policy rules are updated by
24142 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24143 * and {@param procStateSeq}.
24146 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24147 if (DEBUG_NETWORK) {
24148 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24149 + uid + " seq: " + procStateSeq);
24152 synchronized (ActivityManagerService.this) {
24153 record = mActiveUids.get(uid);
24154 if (record == null) {
24155 if (DEBUG_NETWORK) {
24156 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24157 + " procStateSeq: " + procStateSeq);
24162 synchronized (record.networkStateLock) {
24163 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24164 if (DEBUG_NETWORK) {
24165 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24166 + " been handled for uid: " + uid);
24170 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24171 if (record.curProcStateSeq > procStateSeq) {
24172 if (DEBUG_NETWORK) {
24173 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24174 + ", curProcstateSeq: " + record.curProcStateSeq
24175 + ", procStateSeq: " + procStateSeq);
24179 if (record.waitingForNetwork) {
24180 if (DEBUG_NETWORK) {
24181 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24182 + ", procStateSeq: " + procStateSeq);
24184 record.networkStateLock.notifyAll();
24190 * Called after virtual display Id is updated by
24191 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24192 * {@param vrVr2dDisplayId}.
24195 public void setVr2dDisplayId(int vr2dDisplayId) {
24197 Slog.d(TAG, "setVr2dDisplayId called for: " +
24200 synchronized (ActivityManagerService.this) {
24201 mVr2dDisplayId = vr2dDisplayId;
24206 public void saveANRState(String reason) {
24207 synchronized (ActivityManagerService.this) {
24208 final StringWriter sw = new StringWriter();
24209 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24210 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24211 if (reason != null) {
24212 pw.println(" Reason: " + reason);
24215 mActivityStarter.dump(pw, " ", null);
24217 pw.println("-------------------------------------------------------------------------------");
24218 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24219 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24224 mLastANRState = sw.toString();
24229 public void clearSavedANRState() {
24230 synchronized (ActivityManagerService.this) {
24231 mLastANRState = null;
24236 public void setFocusedActivity(IBinder token) {
24237 synchronized (ActivityManagerService.this) {
24238 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24240 throw new IllegalArgumentException(
24241 "setFocusedActivity: No activity record matching token=" + token);
24243 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24244 r, "setFocusedActivity")) {
24245 mStackSupervisor.resumeFocusedStackTopActivityLocked();
24251 public void registerScreenObserver(ScreenObserver observer) {
24252 mScreenObservers.add(observer);
24257 * Called by app main thread to wait for the network policy rules to get updated.
24259 * @param procStateSeq The sequence number indicating the process state change that the main
24260 * thread is interested in.
24263 public void waitForNetworkStateUpdate(long procStateSeq) {
24264 final int callingUid = Binder.getCallingUid();
24265 if (DEBUG_NETWORK) {
24266 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24269 synchronized (this) {
24270 record = mActiveUids.get(callingUid);
24271 if (record == null) {
24275 synchronized (record.networkStateLock) {
24276 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24277 if (DEBUG_NETWORK) {
24278 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24279 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24280 + " lastProcStateSeqDispatchedToObservers: "
24281 + record.lastDispatchedProcStateSeq);
24285 if (record.curProcStateSeq > procStateSeq) {
24286 if (DEBUG_NETWORK) {
24287 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24288 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24289 + ", procStateSeq: " + procStateSeq);
24293 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24294 if (DEBUG_NETWORK) {
24295 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24296 + procStateSeq + ", so no need to wait. Uid: "
24297 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24298 + record.lastNetworkUpdatedProcStateSeq);
24303 if (DEBUG_NETWORK) {
24304 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24305 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24307 final long startTime = SystemClock.uptimeMillis();
24308 record.waitingForNetwork = true;
24309 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24310 record.waitingForNetwork = false;
24311 final long totalTime = SystemClock.uptimeMillis() - startTime;
24312 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24313 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24314 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24315 + procStateSeq + " UidRec: " + record
24316 + " validateUidRec: " + mValidateUids.get(callingUid));
24318 } catch (InterruptedException e) {
24319 Thread.currentThread().interrupt();
24324 public void waitForBroadcastIdle(PrintWriter pw) {
24325 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24327 boolean idle = true;
24328 synchronized (this) {
24329 for (BroadcastQueue queue : mBroadcastQueues) {
24330 if (!queue.isIdle()) {
24331 final String msg = "Waiting for queue " + queue + " to become idle...";
24341 final String msg = "All broadcast queues are idle!";
24347 SystemClock.sleep(1000);
24353 * Return the user id of the last resumed activity.
24356 public @UserIdInt int getLastResumedActivityUserId() {
24357 enforceCallingPermission(
24358 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24359 synchronized (this) {
24360 if (mLastResumedActivity == null) {
24361 return mUserController.getCurrentUserIdLocked();
24363 return mLastResumedActivity.userId;
24368 * An implementation of IAppTask, that allows an app to manage its own tasks via
24369 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24370 * only the process that calls getAppTasks() can call the AppTask methods.
24372 class AppTaskImpl extends IAppTask.Stub {
24373 private int mTaskId;
24374 private int mCallingUid;
24376 public AppTaskImpl(int taskId, int callingUid) {
24378 mCallingUid = callingUid;
24381 private void checkCaller() {
24382 if (mCallingUid != Binder.getCallingUid()) {
24383 throw new SecurityException("Caller " + mCallingUid
24384 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24389 public void finishAndRemoveTask() {
24392 synchronized (ActivityManagerService.this) {
24393 long origId = Binder.clearCallingIdentity();
24395 // We remove the task from recents to preserve backwards
24396 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24397 REMOVE_FROM_RECENTS)) {
24398 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24401 Binder.restoreCallingIdentity(origId);
24407 public ActivityManager.RecentTaskInfo getTaskInfo() {
24410 synchronized (ActivityManagerService.this) {
24411 long origId = Binder.clearCallingIdentity();
24413 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24415 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24417 return createRecentTaskInfoFromTaskRecord(tr);
24419 Binder.restoreCallingIdentity(origId);
24425 public void moveToFront() {
24427 // Will bring task to front if it already has a root activity.
24428 final long origId = Binder.clearCallingIdentity();
24430 synchronized (this) {
24431 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24434 Binder.restoreCallingIdentity(origId);
24439 public int startActivity(IBinder whoThread, String callingPackage,
24440 Intent intent, String resolvedType, Bundle bOptions) {
24443 int callingUser = UserHandle.getCallingUserId();
24445 IApplicationThread appThread;
24446 synchronized (ActivityManagerService.this) {
24447 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24449 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24451 appThread = IApplicationThread.Stub.asInterface(whoThread);
24452 if (appThread == null) {
24453 throw new IllegalArgumentException("Bad app thread " + appThread);
24456 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24457 resolvedType, null, null, null, null, 0, 0, null, null,
24458 null, bOptions, false, callingUser, tr, "AppTaskImpl");
24462 public void setExcludeFromRecents(boolean exclude) {
24465 synchronized (ActivityManagerService.this) {
24466 long origId = Binder.clearCallingIdentity();
24468 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24470 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24472 Intent intent = tr.getBaseIntent();
24474 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24476 intent.setFlags(intent.getFlags()
24477 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24480 Binder.restoreCallingIdentity(origId);
24487 * Kill processes for the user with id userId and that depend on the package named packageName
24490 public void killPackageDependents(String packageName, int userId) {
24491 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24492 if (packageName == null) {
24493 throw new NullPointerException(
24494 "Cannot kill the dependents of a package without its name.");
24497 long callingId = Binder.clearCallingIdentity();
24498 IPackageManager pm = AppGlobals.getPackageManager();
24501 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24502 } catch (RemoteException e) {
24504 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24505 throw new IllegalArgumentException(
24506 "Cannot kill dependents of non-existing package " + packageName);
24509 synchronized(this) {
24510 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24511 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24512 "dep: " + packageName);
24515 Binder.restoreCallingIdentity(callingId);
24520 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24521 throws RemoteException {
24522 final long callingId = Binder.clearCallingIdentity();
24524 mKeyguardController.dismissKeyguard(token, callback);
24526 Binder.restoreCallingIdentity(callingId);
24531 public int restartUserInBackground(final int userId) {
24532 return mUserController.restartUser(userId, /* foreground */ false);
24536 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24537 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24538 "scheduleApplicationInfoChanged()");
24540 synchronized (this) {
24541 final long origId = Binder.clearCallingIdentity();
24543 updateApplicationInfoLocked(packageNames, userId);
24545 Binder.restoreCallingIdentity(origId);
24550 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24551 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24552 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24553 final ProcessRecord app = mLruProcesses.get(i);
24554 if (app.thread == null) {
24558 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24562 final int packageCount = app.pkgList.size();
24563 for (int j = 0; j < packageCount; j++) {
24564 final String packageName = app.pkgList.keyAt(j);
24565 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24567 final ApplicationInfo ai = AppGlobals.getPackageManager()
24568 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24570 app.thread.scheduleApplicationInfoChanged(ai);
24572 } catch (RemoteException e) {
24573 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24574 packageName, app));
24582 * Attach an agent to the specified process (proces name or PID)
24584 public void attachAgent(String process, String path) {
24586 synchronized (this) {
24587 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24588 if (proc == null || proc.thread == null) {
24589 throw new IllegalArgumentException("Unknown process: " + process);
24592 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24593 if (!isDebuggable) {
24594 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24595 throw new SecurityException("Process not debuggable: " + proc);
24599 proc.thread.attachAgent(path);
24601 } catch (RemoteException e) {
24602 throw new IllegalStateException("Process disappeared");
24607 public static class Injector {
24608 private NetworkManagementInternal mNmi;
24610 public Context getContext() {
24614 public AppOpsService getAppOpsService(File file, Handler handler) {
24615 return new AppOpsService(file, handler);
24618 public Handler getUiHandler(ActivityManagerService service) {
24619 return service.new UiHandler();
24622 public boolean isNetworkRestrictedForUid(int uid) {
24623 if (ensureHasNetworkManagementInternal()) {
24624 return mNmi.isNetworkRestrictedForUid(uid);
24629 private boolean ensureHasNetworkManagementInternal() {
24630 if (mNmi == null) {
24631 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24633 return mNmi != null;
24638 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24639 throws RemoteException {
24640 synchronized (this) {
24641 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24645 final long origId = Binder.clearCallingIdentity();
24647 r.setShowWhenLocked(showWhenLocked);
24649 Binder.restoreCallingIdentity(origId);
24655 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24656 synchronized (this) {
24657 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24661 final long origId = Binder.clearCallingIdentity();
24663 r.setTurnScreenOn(turnScreenOn);
24665 Binder.restoreCallingIdentity(origId);