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 com.android.internal.telephony.TelephonyIntents;
20 import com.google.android.collect.Lists;
21 import com.google.android.collect.Maps;
22 import com.android.internal.R;
23 import com.android.internal.annotations.GuardedBy;
24 import com.android.internal.app.AssistUtils;
25 import com.android.internal.app.DumpHeapActivity;
26 import com.android.internal.app.IAppOpsCallback;
27 import com.android.internal.app.IAppOpsService;
28 import com.android.internal.app.IVoiceInteractor;
29 import com.android.internal.app.ProcessMap;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.app.procstats.ProcessStats;
32 import com.android.internal.os.BackgroundThread;
33 import com.android.internal.os.BatteryStatsImpl;
34 import com.android.internal.os.IResultReceiver;
35 import com.android.internal.os.ProcessCpuTracker;
36 import com.android.internal.os.TransferPipe;
37 import com.android.internal.os.Zygote;
38 import com.android.internal.os.InstallerConnection.InstallerException;
39 import com.android.internal.util.ArrayUtils;
40 import com.android.internal.util.FastPrintWriter;
41 import com.android.internal.util.FastXmlSerializer;
42 import com.android.internal.util.MemInfoReader;
43 import com.android.internal.util.Preconditions;
44 import com.android.server.AppOpsService;
45 import com.android.server.AttributeCache;
46 import com.android.server.DeviceIdleController;
47 import com.android.server.IntentResolver;
48 import com.android.server.LocalServices;
49 import com.android.server.LockGuard;
50 import com.android.server.ServiceThread;
51 import com.android.server.SystemService;
52 import com.android.server.SystemServiceManager;
53 import com.android.server.Watchdog;
54 import com.android.server.am.ActivityStack.ActivityState;
55 import com.android.server.firewall.IntentFirewall;
56 import com.android.server.pm.Installer;
57 import com.android.server.statusbar.StatusBarManagerInternal;
58 import com.android.server.vr.VrManagerInternal;
59 import com.android.server.wm.WindowManagerService;
61 import org.xmlpull.v1.XmlPullParser;
62 import org.xmlpull.v1.XmlPullParserException;
63 import org.xmlpull.v1.XmlSerializer;
65 import android.Manifest;
66 import android.Manifest.permission;
67 import android.annotation.NonNull;
68 import android.annotation.UserIdInt;
69 import android.app.Activity;
70 import android.app.ActivityManager;
71 import android.app.ActivityManager.RunningTaskInfo;
72 import android.app.ActivityManager.StackId;
73 import android.app.ActivityManager.StackInfo;
74 import android.app.ActivityManager.TaskThumbnailInfo;
75 import android.app.ActivityManagerInternal;
76 import android.app.ActivityManagerInternal.SleepToken;
77 import android.app.ActivityManagerNative;
78 import android.app.ActivityOptions;
79 import android.app.ActivityThread;
80 import android.app.AlertDialog;
81 import android.app.AppGlobals;
82 import android.app.AppOpsManager;
83 import android.app.ApplicationErrorReport;
84 import android.app.ApplicationThreadNative;
85 import android.app.BroadcastOptions;
86 import android.app.Dialog;
87 import android.app.IActivityContainer;
88 import android.app.IActivityContainerCallback;
89 import android.app.IActivityController;
90 import android.app.IAppTask;
91 import android.app.IApplicationThread;
92 import android.app.IInstrumentationWatcher;
93 import android.app.INotificationManager;
94 import android.app.IProcessObserver;
95 import android.app.IServiceConnection;
96 import android.app.IStopUserCallback;
97 import android.app.ITaskStackListener;
98 import android.app.IUiAutomationConnection;
99 import android.app.IUidObserver;
100 import android.app.IUserSwitchObserver;
101 import android.app.Instrumentation;
102 import android.app.Notification;
103 import android.app.NotificationManager;
104 import android.app.PendingIntent;
105 import android.app.ProfilerInfo;
106 import android.app.admin.DevicePolicyManager;
107 import android.app.assist.AssistContent;
108 import android.app.assist.AssistStructure;
109 import android.app.backup.IBackupManager;
110 import android.app.usage.UsageEvents;
111 import android.app.usage.UsageStatsManagerInternal;
112 import android.appwidget.AppWidgetManager;
113 import android.content.ActivityNotFoundException;
114 import android.content.BroadcastReceiver;
115 import android.content.ClipData;
116 import android.content.ComponentCallbacks2;
117 import android.content.ComponentName;
118 import android.content.ContentProvider;
119 import android.content.ContentResolver;
120 import android.content.Context;
121 import android.content.DialogInterface;
122 import android.content.IContentProvider;
123 import android.content.IIntentReceiver;
124 import android.content.IIntentSender;
125 import android.content.Intent;
126 import android.content.IntentFilter;
127 import android.content.IntentSender;
128 import android.content.pm.ActivityInfo;
129 import android.content.pm.ApplicationInfo;
130 import android.content.pm.ConfigurationInfo;
131 import android.content.pm.IPackageDataObserver;
132 import android.content.pm.IPackageManager;
133 import android.content.pm.InstrumentationInfo;
134 import android.content.pm.PackageInfo;
135 import android.content.pm.PackageManager;
136 import android.content.pm.PackageManager.NameNotFoundException;
137 import android.content.pm.PackageManagerInternal;
138 import android.content.pm.ParceledListSlice;
139 import android.content.pm.PathPermission;
140 import android.content.pm.PermissionInfo;
141 import android.content.pm.ProviderInfo;
142 import android.content.pm.ResolveInfo;
143 import android.content.pm.ServiceInfo;
144 import android.content.pm.UserInfo;
145 import android.content.res.CompatibilityInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Bitmap;
150 import android.graphics.Point;
151 import android.graphics.Rect;
152 import android.location.LocationManager;
153 import android.net.Proxy;
154 import android.net.ProxyInfo;
155 import android.net.Uri;
156 import android.os.BatteryStats;
157 import android.os.Binder;
158 import android.os.Build;
159 import android.os.Bundle;
160 import android.os.Debug;
161 import android.os.DropBoxManager;
162 import android.os.Environment;
163 import android.os.FactoryTest;
164 import android.os.FileObserver;
165 import android.os.FileUtils;
166 import android.os.Handler;
167 import android.os.IBinder;
168 import android.os.IPermissionController;
169 import android.os.IProcessInfoService;
170 import android.os.IProgressListener;
171 import android.os.LocaleList;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PersistableBundle;
177 import android.os.PowerManager;
178 import android.os.PowerManagerInternal;
179 import android.os.Process;
180 import android.os.RemoteCallbackList;
181 import android.os.RemoteException;
182 import android.os.ResultReceiver;
183 import android.os.ServiceManager;
184 import android.os.StrictMode;
185 import android.os.SystemClock;
186 import android.os.SystemProperties;
187 import android.os.Trace;
188 import android.os.TransactionTooLargeException;
189 import android.os.UpdateLock;
190 import android.os.UserHandle;
191 import android.os.UserManager;
192 import android.os.WorkSource;
193 import android.provider.Downloads;
194 import android.os.storage.IMountService;
195 import android.os.storage.MountServiceInternal;
196 import android.os.storage.StorageManager;
197 import android.provider.Settings;
198 import android.service.voice.IVoiceInteractionSession;
199 import android.service.voice.VoiceInteractionManagerInternal;
200 import android.service.voice.VoiceInteractionSession;
201 import android.telecom.TelecomManager;
202 import android.text.format.DateUtils;
203 import android.text.format.Time;
204 import android.text.style.SuggestionSpan;
205 import android.util.ArrayMap;
206 import android.util.ArraySet;
207 import android.util.AtomicFile;
208 import android.util.DebugUtils;
209 import android.util.DisplayMetrics;
210 import android.util.EventLog;
211 import android.util.Log;
212 import android.util.Pair;
213 import android.util.PrintWriterPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.TimeUtils;
217 import android.util.Xml;
218 import android.view.Display;
219 import android.view.Gravity;
220 import android.view.LayoutInflater;
221 import android.view.View;
222 import android.view.WindowManager;
225 import java.io.FileDescriptor;
226 import java.io.FileInputStream;
227 import java.io.FileNotFoundException;
228 import java.io.FileOutputStream;
229 import java.io.IOException;
230 import java.io.InputStreamReader;
231 import java.io.PrintWriter;
232 import java.io.StringWriter;
233 import java.lang.ref.WeakReference;
234 import java.nio.charset.StandardCharsets;
235 import java.util.ArrayList;
236 import java.util.Arrays;
237 import java.util.Collections;
238 import java.util.Comparator;
239 import java.util.HashMap;
240 import java.util.HashSet;
241 import java.util.Iterator;
242 import java.util.List;
243 import java.util.Locale;
244 import java.util.Map;
245 import java.util.Objects;
246 import java.util.Set;
247 import java.util.concurrent.atomic.AtomicBoolean;
248 import java.util.concurrent.atomic.AtomicLong;
250 import dalvik.system.VMRuntime;
252 import libcore.io.IoUtils;
253 import libcore.util.EmptyArray;
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270 import static android.content.pm.PackageManager.GET_PROVIDERS;
271 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
273 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
274 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278 import static android.os.Process.PROC_CHAR;
279 import static android.os.Process.PROC_OUT_LONG;
280 import static android.os.Process.PROC_PARENS;
281 import static android.os.Process.PROC_SPACE_TERM;
282 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283 import static android.provider.Settings.Global.DEBUG_APP;
284 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289 import static android.provider.Settings.System.FONT_SCALE;
290 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.readIntAttribute;
292 import static com.android.internal.util.XmlUtils.readLongAttribute;
293 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294 import static com.android.internal.util.XmlUtils.writeIntAttribute;
295 import static com.android.internal.util.XmlUtils.writeLongAttribute;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372 import static org.xmlpull.v1.XmlPullParser.START_TAG;
374 public final class ActivityManagerService extends ActivityManagerNative
375 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
377 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386 private static final String TAG_LRU = TAG + POSTFIX_LRU;
387 private static final String TAG_MU = TAG + POSTFIX_MU;
388 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389 private static final String TAG_POWER = TAG + POSTFIX_POWER;
390 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393 private static final String TAG_PSS = TAG + POSTFIX_PSS;
394 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396 private static final String TAG_STACK = TAG + POSTFIX_STACK;
397 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
403 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404 // here so that while the job scheduler can depend on AMS, the other way around
405 // need not be the case.
406 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
408 /** Control over CPU and battery monitoring */
409 // write battery stats every 30 minutes.
410 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411 static final boolean MONITOR_CPU_USAGE = true;
412 // don't sample cpu less than every 5 seconds.
413 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414 // wait possibly forever for next cpu sample.
415 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416 static final boolean MONITOR_THREAD_CPU_USAGE = false;
418 // The flags that are set for all calls we make to the package manager.
419 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
421 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
423 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
425 // Amount of time after a call to stopAppSwitches() during which we will
426 // prevent further untrusted switches from happening.
427 static final long APP_SWITCH_DELAY_TIME = 5*1000;
429 // How long we wait for a launched process to attach to the activity manager
430 // before we decide it's never going to come up for real.
431 static final int PROC_START_TIMEOUT = 10*1000;
432 // How long we wait for an attached process to publish its content providers
433 // before we decide it must be hung.
434 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
436 // How long we will retain processes hosting content providers in the "last activity"
437 // state before allowing them to drop down to the regular cached LRU list. This is
438 // to avoid thrashing of provider processes under low memory situations.
439 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
441 // How long we wait for a launched process to attach to the activity manager
442 // before we decide it's never going to come up for real, when the process was
443 // started with a wrapper for instrumentation (such as Valgrind) because it
444 // could take much longer than usual.
445 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
447 // How long to wait after going idle before forcing apps to GC.
448 static final int GC_TIMEOUT = 5*1000;
450 // The minimum amount of time between successive GC requests for a process.
451 static final int GC_MIN_INTERVAL = 60*1000;
453 // The minimum amount of time between successive PSS requests for a process.
454 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
456 // The minimum amount of time between successive PSS requests for a process
457 // when the request is due to the memory state being lowered.
458 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
460 // The rate at which we check for apps using excessive power -- 15 mins.
461 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
463 // The minimum sample duration we will allow before deciding we have
464 // enough data on wake locks to start killing things.
465 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
467 // The minimum sample duration we will allow before deciding we have
468 // enough data on CPU usage to start killing things.
469 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
471 // How long we allow a receiver to run before giving up on it.
472 static final int BROADCAST_FG_TIMEOUT = 10*1000;
473 static final int BROADCAST_BG_TIMEOUT = 60*1000;
475 // How long we wait until we timeout on key dispatching.
476 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
478 // How long we wait until we timeout on key dispatching during instrumentation.
479 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
481 // This is the amount of time an app needs to be running a foreground service before
482 // we will consider it to be doing interaction for usage stats.
483 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
485 // Maximum amount of time we will allow to elapse before re-reporting usage stats
486 // interaction with foreground processes.
487 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
489 // This is the amount of time we allow an app to settle after it goes into the background,
490 // before we start restricting what it can do.
491 static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
493 // How long to wait in getAssistContextExtras for the activity and foreground services
494 // to respond with the result.
495 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
497 // How long top wait when going through the modern assist (which doesn't need to block
498 // on getting this result before starting to launch its UI).
499 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
501 // Maximum number of persisted Uri grants a package is allowed
502 static final int MAX_PERSISTED_URI_GRANTS = 128;
504 static final int MY_PID = Process.myPid();
506 static final String[] EMPTY_STRING_ARRAY = new String[0];
508 // How many bytes to write into the dropbox log before truncating
509 static final int DROPBOX_MAX_SIZE = 192 * 1024;
510 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511 // as one line, but close enough for now.
512 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
514 // Access modes for handleIncomingUser.
515 static final int ALLOW_NON_FULL = 0;
516 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517 static final int ALLOW_FULL_ONLY = 2;
519 // Delay in notifying task stack change listeners (in millis)
520 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
522 // Necessary ApplicationInfo flags to mark an app as persistent
523 private static final int PERSISTENT_MASK =
524 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
526 // Intent sent when remote bugreport collection has been completed
527 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528 "android.intent.action.REMOTE_BUGREPORT_FINISHED";
530 // Delay to disable app launch boost
531 static final int APP_BOOST_MESSAGE_DELAY = 3000;
532 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533 static final int APP_BOOST_TIMEOUT = 2500;
535 // Used to indicate that a task is removed it should also be removed from recents.
536 private static final boolean REMOVE_FROM_RECENTS = true;
537 // Used to indicate that an app transition should be animated.
538 static final boolean ANIMATE = true;
540 // Determines whether to take full screen screenshots
541 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542 public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
544 private static native int nativeMigrateToBoost();
545 private static native int nativeMigrateFromBoost();
546 private boolean mIsBoosted = false;
547 private long mBoostStartTime = 0;
549 /** All system services */
550 SystemServiceManager mSystemServiceManager;
552 private Installer mInstaller;
554 /** Run all ActivityStacks through this */
555 final ActivityStackSupervisor mStackSupervisor;
557 final ActivityStarter mActivityStarter;
559 /** Task stack change listeners. */
560 private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561 new RemoteCallbackList<ITaskStackListener>();
563 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
565 public IntentFirewall mIntentFirewall;
567 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568 // default actuion automatically. Important for devices without direct input
570 private boolean mShowDialogs = true;
571 private boolean mInVrMode = false;
573 // Whether we should use SCHED_FIFO for UI and RenderThreads.
574 private boolean mUseFifoUiScheduling = false;
576 BroadcastQueue mFgBroadcastQueue;
577 BroadcastQueue mBgBroadcastQueue;
578 // Convenient for easy iteration over the queues. Foreground is first
579 // so that dispatch of foreground broadcasts gets precedence.
580 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
582 BroadcastStats mLastBroadcastStats;
583 BroadcastStats mCurBroadcastStats;
585 BroadcastQueue broadcastQueueForIntent(Intent intent) {
586 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588 "Broadcast intent " + intent + " on "
589 + (isFg ? "foreground" : "background") + " queue");
590 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
594 * Activity we have told the window manager to have key focus.
596 ActivityRecord mFocusedActivity = null;
599 * User id of the last activity mFocusedActivity was set to.
601 private int mLastFocusedUserId;
604 * If non-null, we are tracking the time the user spends in the currently focused app.
606 private AppTimeTracker mCurAppTimeTracker;
609 * List of intents that were used to start the most recent tasks.
611 final RecentTasks mRecentTasks;
614 * For addAppTask: cached of the last activity component that was added.
616 ComponentName mLastAddedTaskComponent;
619 * For addAppTask: cached of the last activity uid that was added.
621 int mLastAddedTaskUid;
624 * For addAppTask: cached of the last ActivityInfo that was added.
626 ActivityInfo mLastAddedTaskActivity;
629 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
631 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
634 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
636 String mDeviceOwnerName;
638 final UserController mUserController;
640 final AppErrors mAppErrors;
642 boolean mDoingSetFocusedActivity;
644 public boolean canShowErrorDialogs() {
645 return mShowDialogs && !mSleeping && !mShuttingDown
646 && mLockScreenShown != LOCK_SCREEN_SHOWN;
649 private static final class PriorityState {
650 // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
651 // the current thread is currently in. When it drops down to zero, we will no longer boost
652 // the thread's priority.
653 private int regionCounter = 0;
655 // The thread's previous priority before boosting.
656 private int prevPriority = Integer.MIN_VALUE;
659 static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
660 @Override protected PriorityState initialValue() {
661 return new PriorityState();
665 static void boostPriorityForLockedSection() {
666 int tid = Process.myTid();
667 int prevPriority = Process.getThreadPriority(tid);
668 PriorityState state = sThreadPriorityState.get();
669 if (state.regionCounter == 0 && prevPriority > -2) {
670 state.prevPriority = prevPriority;
671 Process.setThreadPriority(tid, -2);
673 state.regionCounter++;
676 static void resetPriorityAfterLockedSection() {
677 PriorityState state = sThreadPriorityState.get();
678 state.regionCounter--;
679 if (state.regionCounter == 0 && state.prevPriority > -2) {
680 Process.setThreadPriority(Process.myTid(), state.prevPriority);
684 public class PendingAssistExtras extends Binder implements Runnable {
685 public final ActivityRecord activity;
686 public final Bundle extras;
687 public final Intent intent;
688 public final String hint;
689 public final IResultReceiver receiver;
690 public final int userHandle;
691 public boolean haveResult = false;
692 public Bundle result = null;
693 public AssistStructure structure = null;
694 public AssistContent content = null;
695 public Bundle receiverExtras;
697 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
699 activity = _activity;
703 receiver = _receiver;
704 receiverExtras = _receiverExtras;
705 userHandle = _userHandle;
709 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710 synchronized (this) {
714 pendingAssistExtrasTimedOut(this);
718 final ArrayList<PendingAssistExtras> mPendingAssistExtras
719 = new ArrayList<PendingAssistExtras>();
722 * Process management.
724 final ProcessList mProcessList = new ProcessList();
727 * All of the applications we currently have running organized by name.
728 * The keys are strings of the application package name (as
729 * returned by the package manager), and the keys are ApplicationRecord
732 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
735 * Tracking long-term execution of processes to look for abuse and other
738 final ProcessStatsService mProcessStats;
741 * The currently running isolated processes.
743 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
746 * Counter for assigning isolated process uids, to avoid frequently reusing the
749 int mNextIsolatedProcessUid = 0;
752 * The currently running heavy-weight process, if any.
754 ProcessRecord mHeavyWeightProcess = null;
757 * All of the processes we currently have running organized by pid.
758 * The keys are the pid running the application.
760 * <p>NOTE: This object is protected by its own lock, NOT the global
761 * activity manager lock!
763 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
766 * All of the processes that have been forced to be foreground. The key
767 * is the pid of the caller who requested it (we hold a death
770 abstract class ForegroundToken implements IBinder.DeathRecipient {
774 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
777 * List of records for processes that someone had tried to start before the
778 * system was ready. We don't start them at that point, but ensure they
779 * are started by the time booting is complete.
781 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
784 * List of persistent applications that are in the process
787 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
790 * Processes that are being forcibly torn down.
792 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
795 * List of running applications, sorted by recent usage.
796 * The first entry in the list is the least recently used.
798 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
801 * Where in mLruProcesses that the processes hosting activities start.
803 int mLruProcessActivityStart = 0;
806 * Where in mLruProcesses that the processes hosting services start.
807 * This is after (lower index) than mLruProcessesActivityStart.
809 int mLruProcessServiceStart = 0;
812 * List of processes that should gc as soon as things are idle.
814 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
817 * Processes we want to collect PSS data from.
819 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
821 private boolean mBinderTransactionTrackingEnabled = false;
824 * Last time we requested PSS data of all processes.
826 long mLastFullPssTime = SystemClock.uptimeMillis();
829 * If set, the next time we collect PSS data we should do a full collection
830 * with data from native processes and the kernel.
832 boolean mFullPssPending = false;
835 * This is the process holding what we currently consider to be
836 * the "home" activity.
838 ProcessRecord mHomeProcess;
841 * This is the process holding the activity the user last visited that
842 * is in a different process from the one they are currently in.
844 ProcessRecord mPreviousProcess;
847 * The time at which the previous process was last visible.
849 long mPreviousProcessVisibleTime;
852 * Track all uids that have actively running processes.
854 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
857 * This is for verifying the UID report flow.
859 static final boolean VALIDATE_UID_STATES = true;
860 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
863 * Packages that the user has asked to have run in screen size
864 * compatibility mode instead of filling the screen.
866 final CompatModePackages mCompatModePackages;
869 * Set of IntentSenderRecord objects that are currently active.
871 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
875 * Fingerprints (hashCode()) of stack traces that we've
876 * already logged DropBox entries for. Guarded by itself. If
877 * something (rogue user app) forces this over
878 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
880 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
884 * Strict Mode background batched logging state.
886 * The string buffer is guarded by itself, and its lock is also
887 * used to determine if another batched write is already
890 private final StringBuilder mStrictModeBuffer = new StringBuilder();
893 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
896 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
899 * Resolver for broadcast intents to registered receivers.
900 * Holds BroadcastFilter (subclass of IntentFilter).
902 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
905 protected boolean allowFilterResult(
906 BroadcastFilter filter, List<BroadcastFilter> dest) {
907 IBinder target = filter.receiverList.receiver.asBinder();
908 for (int i = dest.size() - 1; i >= 0; i--) {
909 if (dest.get(i).receiverList.receiver.asBinder() == target) {
917 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919 || userId == filter.owningUserId) {
920 return super.newResult(filter, match, userId);
926 protected BroadcastFilter[] newArray(int size) {
927 return new BroadcastFilter[size];
931 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932 return packageName.equals(filter.packageName);
937 * State of all active sticky broadcasts per user. Keys are the action of the
938 * sticky Intent, values are an ArrayList of all broadcasted intents with
939 * that action (which should usually be one). The SparseArray is keyed
940 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941 * for stickies that are sent to all users.
943 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
946 final ActiveServices mServices;
948 final static class Association {
949 final int mSourceUid;
950 final String mSourceProcess;
951 final int mTargetUid;
952 final ComponentName mTargetComponent;
953 final String mTargetProcess;
961 // states of the source process when the bind occurred.
962 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963 long mLastStateUptime;
964 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965 - ActivityManager.MIN_PROCESS_STATE+1];
967 Association(int sourceUid, String sourceProcess, int targetUid,
968 ComponentName targetComponent, String targetProcess) {
969 mSourceUid = sourceUid;
970 mSourceProcess = sourceProcess;
971 mTargetUid = targetUid;
972 mTargetComponent = targetComponent;
973 mTargetProcess = targetProcess;
978 * When service association tracking is enabled, this is all of the associations we
979 * have seen. Mapping is target uid -> target component -> source uid -> source process name
980 * -> association data.
982 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983 mAssociations = new SparseArray<>();
984 boolean mTrackingAssociations;
987 * Backup/restore process management
989 String mBackupAppName = null;
990 BackupRecord mBackupTarget = null;
992 final ProviderMap mProviderMap;
995 * List of content providers who have clients waiting for them. The
996 * application is currently being launched and the provider will be
997 * removed from this list once it is published.
999 final ArrayList<ContentProviderRecord> mLaunchingProviders
1000 = new ArrayList<ContentProviderRecord>();
1003 * File storing persisted {@link #mGrantedUriPermissions}.
1005 private final AtomicFile mGrantFile;
1007 /** XML constants used in {@link #mGrantFile} */
1008 private static final String TAG_URI_GRANTS = "uri-grants";
1009 private static final String TAG_URI_GRANT = "uri-grant";
1010 private static final String ATTR_USER_HANDLE = "userHandle";
1011 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014 private static final String ATTR_TARGET_PKG = "targetPkg";
1015 private static final String ATTR_URI = "uri";
1016 private static final String ATTR_MODE_FLAGS = "modeFlags";
1017 private static final String ATTR_CREATED_TIME = "createdTime";
1018 private static final String ATTR_PREFIX = "prefix";
1021 * Global set of specific {@link Uri} permissions that have been granted.
1022 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023 * to {@link UriPermission#uri} to {@link UriPermission}.
1026 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1029 public static class GrantUri {
1030 public final int sourceUserId;
1031 public final Uri uri;
1032 public boolean prefix;
1034 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035 this.sourceUserId = sourceUserId;
1037 this.prefix = prefix;
1041 public int hashCode() {
1043 hashCode = 31 * hashCode + sourceUserId;
1044 hashCode = 31 * hashCode + uri.hashCode();
1045 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1050 public boolean equals(Object o) {
1051 if (o instanceof GrantUri) {
1052 GrantUri other = (GrantUri) o;
1053 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054 && prefix == other.prefix;
1060 public String toString() {
1061 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062 if (prefix) result += " [prefix]";
1066 public String toSafeString() {
1067 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068 if (prefix) result += " [prefix]";
1072 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074 ContentProvider.getUriWithoutUserId(uri), false);
1078 CoreSettingsObserver mCoreSettingsObserver;
1080 FontScaleSettingObserver mFontScaleSettingObserver;
1082 private final class FontScaleSettingObserver extends ContentObserver {
1083 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1085 public FontScaleSettingObserver() {
1087 ContentResolver resolver = mContext.getContentResolver();
1088 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1092 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093 if (mFontScaleUri.equals(uri)) {
1094 updateFontScaleIfNeeded(userId);
1100 * Thread-local storage used to carry caller permissions over through
1101 * indirect content-provider access.
1103 private class Identity {
1104 public final IBinder token;
1105 public final int pid;
1106 public final int uid;
1108 Identity(IBinder _token, int _pid, int _uid) {
1115 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1118 * All information we have collected about the runtime performance of
1119 * any user id that can impact battery performance.
1121 final BatteryStatsService mBatteryStatsService;
1124 * Information about component usage
1126 UsageStatsManagerInternal mUsageStatsService;
1129 * Access to DeviceIdleController service.
1131 DeviceIdleController.LocalService mLocalDeviceIdleController;
1134 * Information about and control over application operations
1136 final AppOpsService mAppOpsService;
1139 * Current configuration information. HistoryRecord objects are given
1140 * a reference to this object to indicate which configuration they are
1141 * currently running in, so this object must be kept immutable.
1143 Configuration mConfiguration = new Configuration();
1146 * Current sequencing integer of the configuration, for skipping old
1149 int mConfigurationSeq = 0;
1151 boolean mSuppressResizeConfigChanges = false;
1154 * Hardware-reported OpenGLES version.
1156 final int GL_ES_VERSION;
1159 * List of initialization arguments to pass to all processes when binding applications to them.
1160 * For example, references to the commonly used services.
1162 HashMap<String, IBinder> mAppBindArgs;
1163 HashMap<String, IBinder> mIsolatedAppBindArgs;
1166 * Temporary to avoid allocations. Protected by main lock.
1168 final StringBuilder mStringBuilder = new StringBuilder(256);
1171 * Used to control how we initialize the service.
1173 ComponentName mTopComponent;
1174 String mTopAction = Intent.ACTION_MAIN;
1177 volatile boolean mProcessesReady = false;
1178 volatile boolean mSystemReady = false;
1179 volatile boolean mOnBattery = false;
1180 volatile int mFactoryTest;
1182 @GuardedBy("this") boolean mBooting = false;
1183 @GuardedBy("this") boolean mCallFinishBooting = false;
1184 @GuardedBy("this") boolean mBootAnimationComplete = false;
1185 @GuardedBy("this") boolean mLaunchWarningShown = false;
1186 @GuardedBy("this") boolean mCheckedForSetup = false;
1191 * The time at which we will allow normal application switches again,
1192 * after a call to {@link #stopAppSwitches()}.
1194 long mAppSwitchesAllowedTime;
1197 * This is set to true after the first switch after mAppSwitchesAllowedTime
1198 * is set; any switches after that will clear the time.
1200 boolean mDidAppSwitch;
1203 * Last time (in realtime) at which we checked for power usage.
1205 long mLastPowerCheckRealtime;
1208 * Last time (in uptime) at which we checked for power usage.
1210 long mLastPowerCheckUptime;
1213 * Set while we are wanting to sleep, to prevent any
1214 * activities from being started/resumed.
1216 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1218 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1219 * while in the sleep state until there is a pending transition out of sleep, in which case
1220 * mSleeping is set to false, and remains false while awake.
1222 * Whether mSleeping can quickly toggled between true/false without the device actually
1223 * display changing states is undefined.
1225 private boolean mSleeping = false;
1228 * The process state used for processes that are running the top activities.
1229 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1231 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1234 * Set while we are running a voice interaction. This overrides
1235 * sleeping while it is active.
1237 private IVoiceInteractionSession mRunningVoice;
1240 * For some direct access we need to power manager.
1242 PowerManagerInternal mLocalPowerManager;
1245 * We want to hold a wake lock while running a voice interaction session, since
1246 * this may happen with the screen off and we need to keep the CPU running to
1247 * be able to continue to interact with the user.
1249 PowerManager.WakeLock mVoiceWakeLock;
1252 * State of external calls telling us if the device is awake or asleep.
1254 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1257 * A list of tokens that cause the top activity to be put to sleep.
1258 * They are used by components that may hide and block interaction with underlying
1261 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1263 static final int LOCK_SCREEN_HIDDEN = 0;
1264 static final int LOCK_SCREEN_LEAVING = 1;
1265 static final int LOCK_SCREEN_SHOWN = 2;
1267 * State of external call telling us if the lock screen is shown.
1269 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1272 * Set if we are shutting down the system, similar to sleeping.
1274 boolean mShuttingDown = false;
1277 * Current sequence id for oom_adj computation traversal.
1282 * Current sequence id for process LRU updating.
1287 * Keep track of the non-cached/empty process we last found, to help
1288 * determine how to distribute cached/empty processes next time.
1290 int mNumNonCachedProcs = 0;
1293 * Keep track of the number of cached hidden procs, to balance oom adj
1294 * distribution between those and empty procs.
1296 int mNumCachedHiddenProcs = 0;
1299 * Keep track of the number of service processes we last found, to
1300 * determine on the next iteration which should be B services.
1302 int mNumServiceProcs = 0;
1303 int mNewNumAServiceProcs = 0;
1304 int mNewNumServiceProcs = 0;
1307 * Allow the current computed overall memory level of the system to go down?
1308 * This is set to false when we are killing processes for reasons other than
1309 * memory management, so that the now smaller process list will not be taken as
1310 * an indication that memory is tighter.
1312 boolean mAllowLowerMemLevel = false;
1315 * The last computed memory level, for holding when we are in a state that
1316 * processes are going away for other reasons.
1318 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1321 * The last total number of process we have, to determine if changes actually look
1322 * like a shrinking number of process due to lower RAM.
1324 int mLastNumProcesses;
1327 * The uptime of the last time we performed idle maintenance.
1329 long mLastIdleTime = SystemClock.uptimeMillis();
1332 * Total time spent with RAM that has been added in the past since the last idle time.
1334 long mLowRamTimeSinceLastIdle = 0;
1337 * If RAM is currently low, when that horrible situation started.
1339 long mLowRamStartTime = 0;
1342 * For reporting to battery stats the current top application.
1344 private String mCurResumedPackage = null;
1345 private int mCurResumedUid = -1;
1348 * For reporting to battery stats the apps currently running foreground
1349 * service. The ProcessMap is package/uid tuples; each of these contain
1350 * an array of the currently foreground processes.
1352 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1353 = new ProcessMap<ArrayList<ProcessRecord>>();
1356 * This is set if we had to do a delayed dexopt of an app before launching
1357 * it, to increase the ANR timeouts in that case.
1362 * Set if the systemServer made a call to enterSafeMode.
1367 * If true, we are running under a test environment so will sample PSS from processes
1368 * much more rapidly to try to collect better data when the tests are rapidly
1369 * running through apps.
1371 boolean mTestPssMode = false;
1373 String mDebugApp = null;
1374 boolean mWaitForDebugger = false;
1375 boolean mDebugTransient = false;
1376 String mOrigDebugApp = null;
1377 boolean mOrigWaitForDebugger = false;
1378 boolean mAlwaysFinishActivities = false;
1379 boolean mLenientBackgroundCheck = false;
1380 boolean mForceResizableActivities;
1381 boolean mSupportsMultiWindow;
1382 boolean mSupportsFreeformWindowManagement;
1383 boolean mSupportsPictureInPicture;
1384 boolean mSupportsLeanbackOnly;
1385 Rect mDefaultPinnedStackBounds;
1386 IActivityController mController = null;
1387 boolean mControllerIsAMonkey = false;
1388 String mProfileApp = null;
1389 ProcessRecord mProfileProc = null;
1390 String mProfileFile;
1391 ParcelFileDescriptor mProfileFd;
1392 int mSamplingInterval = 0;
1393 boolean mAutoStopProfiler = false;
1394 int mProfileType = 0;
1395 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1396 String mMemWatchDumpProcName;
1397 String mMemWatchDumpFile;
1398 int mMemWatchDumpPid;
1399 int mMemWatchDumpUid;
1400 String mTrackAllocationApp = null;
1401 String mNativeDebuggingApp = null;
1403 final long[] mTmpLong = new long[2];
1405 static final class ProcessChangeItem {
1406 static final int CHANGE_ACTIVITIES = 1<<0;
1407 static final int CHANGE_PROCESS_STATE = 1<<1;
1412 boolean foregroundActivities;
1415 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1416 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1418 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1419 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1421 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1422 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1424 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1425 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1428 * Runtime CPU use collection thread. This object's lock is used to
1429 * perform synchronization with the thread (notifying it to run).
1431 final Thread mProcessCpuThread;
1434 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1435 * Must acquire this object's lock when accessing it.
1436 * NOTE: this lock will be held while doing long operations (trawling
1437 * through all processes in /proc), so it should never be acquired by
1438 * any critical paths such as when holding the main activity manager lock.
1440 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1441 MONITOR_THREAD_CPU_USAGE);
1442 final AtomicLong mLastCpuTime = new AtomicLong(0);
1443 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1445 long mLastWriteTime = 0;
1448 * Used to retain an update lock when the foreground activity is in
1451 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1454 * Set to true after the system has finished booting.
1456 boolean mBooted = false;
1458 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1459 int mProcessLimitOverride = -1;
1461 WindowManagerService mWindowManager;
1462 final ActivityThread mSystemThread;
1464 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1465 final ProcessRecord mApp;
1467 final IApplicationThread mAppThread;
1469 AppDeathRecipient(ProcessRecord app, int pid,
1470 IApplicationThread thread) {
1471 if (DEBUG_ALL) Slog.v(
1472 TAG, "New death recipient " + this
1473 + " for thread " + thread.asBinder());
1476 mAppThread = thread;
1480 public void binderDied() {
1481 if (DEBUG_ALL) Slog.v(
1482 TAG, "Death received in " + this
1483 + " for thread " + mAppThread.asBinder());
1484 synchronized(ActivityManagerService.this) {
1485 appDiedLocked(mApp, mPid, mAppThread, true);
1490 static final int SHOW_ERROR_UI_MSG = 1;
1491 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1492 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1493 static final int UPDATE_CONFIGURATION_MSG = 4;
1494 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1495 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1496 static final int SERVICE_TIMEOUT_MSG = 12;
1497 static final int UPDATE_TIME_ZONE = 13;
1498 static final int SHOW_UID_ERROR_UI_MSG = 14;
1499 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1500 static final int PROC_START_TIMEOUT_MSG = 20;
1501 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1502 static final int KILL_APPLICATION_MSG = 22;
1503 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1504 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1505 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1506 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1507 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1508 static final int CLEAR_DNS_CACHE_MSG = 28;
1509 static final int UPDATE_HTTP_PROXY_MSG = 29;
1510 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1511 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1512 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1513 static final int REPORT_MEM_USAGE_MSG = 33;
1514 static final int REPORT_USER_SWITCH_MSG = 34;
1515 static final int CONTINUE_USER_SWITCH_MSG = 35;
1516 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1517 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1518 static final int PERSIST_URI_GRANTS_MSG = 38;
1519 static final int REQUEST_ALL_PSS_MSG = 39;
1520 static final int START_PROFILES_MSG = 40;
1521 static final int UPDATE_TIME = 41;
1522 static final int SYSTEM_USER_START_MSG = 42;
1523 static final int SYSTEM_USER_CURRENT_MSG = 43;
1524 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1525 static final int FINISH_BOOTING_MSG = 45;
1526 static final int START_USER_SWITCH_UI_MSG = 46;
1527 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1528 static final int DISMISS_DIALOG_UI_MSG = 48;
1529 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1530 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1531 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1532 static final int DELETE_DUMPHEAP_MSG = 52;
1533 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1534 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1535 static final int REPORT_TIME_TRACKER_MSG = 55;
1536 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1537 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1538 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1539 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1540 static final int IDLE_UIDS_MSG = 60;
1541 static final int SYSTEM_USER_UNLOCK_MSG = 61;
1542 static final int LOG_STACK_STATE = 62;
1543 static final int VR_MODE_CHANGE_MSG = 63;
1544 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1545 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1546 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1547 static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1548 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1549 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 69;
1550 static final int NOTIFY_VR_SLEEPING_MSG = 70;
1552 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1553 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1554 static final int FIRST_COMPAT_MODE_MSG = 300;
1555 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1557 static ServiceThread sKillThread = null;
1558 static KillHandler sKillHandler = null;
1560 CompatModeDialog mCompatModeDialog;
1561 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1562 long mLastMemUsageReportTime = 0;
1565 * Flag whether the current user is a "monkey", i.e. whether
1566 * the UI is driven by a UI automation tool.
1568 private boolean mUserIsMonkey;
1570 /** Flag whether the device has a Recents UI */
1571 boolean mHasRecents;
1573 /** The dimensions of the thumbnails in the Recents UI. */
1574 int mThumbnailWidth;
1575 int mThumbnailHeight;
1576 float mFullscreenThumbnailScale;
1578 final ServiceThread mHandlerThread;
1579 final MainHandler mHandler;
1580 final UiHandler mUiHandler;
1582 PackageManagerInternal mPackageManagerInt;
1584 // VoiceInteraction session ID that changes for each new request except when
1585 // being called for multiwindow assist in a single session.
1586 private int mViSessionId = 1000;
1588 final boolean mPermissionReviewRequired;
1590 final class KillHandler extends Handler {
1591 static final int KILL_PROCESS_GROUP_MSG = 4000;
1593 public KillHandler(Looper looper) {
1594 super(looper, null, true);
1598 public void handleMessage(Message msg) {
1600 case KILL_PROCESS_GROUP_MSG:
1602 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1603 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1604 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1609 super.handleMessage(msg);
1614 final class UiHandler extends Handler {
1615 public UiHandler() {
1616 super(com.android.server.UiThread.get().getLooper(), null, true);
1620 public void handleMessage(Message msg) {
1622 case SHOW_ERROR_UI_MSG: {
1623 mAppErrors.handleShowAppErrorUi(msg);
1624 ensureBootCompleted();
1626 case SHOW_NOT_RESPONDING_UI_MSG: {
1627 mAppErrors.handleShowAnrUi(msg);
1628 ensureBootCompleted();
1630 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1631 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1632 synchronized (ActivityManagerService.this) {
1633 ProcessRecord proc = (ProcessRecord) data.get("app");
1635 Slog.e(TAG, "App not found when showing strict mode dialog.");
1638 if (proc.crashDialog != null) {
1639 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1642 AppErrorResult res = (AppErrorResult) data.get("result");
1643 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1644 Dialog d = new StrictModeViolationDialog(mContext,
1645 ActivityManagerService.this, res, proc);
1647 proc.crashDialog = d;
1649 // The device is asleep, so just pretend that the user
1650 // saw a crash dialog and hit "force quit".
1654 ensureBootCompleted();
1656 case SHOW_FACTORY_ERROR_UI_MSG: {
1657 Dialog d = new FactoryErrorDialog(
1658 mContext, msg.getData().getCharSequence("msg"));
1660 ensureBootCompleted();
1662 case WAIT_FOR_DEBUGGER_UI_MSG: {
1663 synchronized (ActivityManagerService.this) {
1664 ProcessRecord app = (ProcessRecord)msg.obj;
1665 if (msg.arg1 != 0) {
1666 if (!app.waitedForDebugger) {
1667 Dialog d = new AppWaitingForDebuggerDialog(
1668 ActivityManagerService.this,
1671 app.waitedForDebugger = true;
1675 if (app.waitDialog != null) {
1676 app.waitDialog.dismiss();
1677 app.waitDialog = null;
1682 case SHOW_UID_ERROR_UI_MSG: {
1684 AlertDialog d = new BaseErrorDialog(mContext);
1685 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686 d.setCancelable(false);
1687 d.setTitle(mContext.getText(R.string.android_system_label));
1688 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1689 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1694 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1696 AlertDialog d = new BaseErrorDialog(mContext);
1697 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1698 d.setCancelable(false);
1699 d.setTitle(mContext.getText(R.string.android_system_label));
1700 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1701 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1702 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1706 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1707 synchronized (ActivityManagerService.this) {
1708 ActivityRecord ar = (ActivityRecord) msg.obj;
1709 if (mCompatModeDialog != null) {
1710 if (mCompatModeDialog.mAppInfo.packageName.equals(
1711 ar.info.applicationInfo.packageName)) {
1714 mCompatModeDialog.dismiss();
1715 mCompatModeDialog = null;
1717 if (ar != null && false) {
1718 if (mCompatModePackages.getPackageAskCompatModeLocked(
1720 int mode = mCompatModePackages.computeCompatModeLocked(
1721 ar.info.applicationInfo);
1722 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1723 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1724 mCompatModeDialog = new CompatModeDialog(
1725 ActivityManagerService.this, mContext,
1726 ar.info.applicationInfo);
1727 mCompatModeDialog.show();
1734 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1735 synchronized (ActivityManagerService.this) {
1736 final ActivityRecord ar = (ActivityRecord) msg.obj;
1737 if (mUnsupportedDisplaySizeDialog != null) {
1738 mUnsupportedDisplaySizeDialog.dismiss();
1739 mUnsupportedDisplaySizeDialog = null;
1741 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1743 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1744 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1745 mUnsupportedDisplaySizeDialog.show();
1750 case START_USER_SWITCH_UI_MSG: {
1751 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1754 case DISMISS_DIALOG_UI_MSG: {
1755 final Dialog d = (Dialog) msg.obj;
1759 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1760 dispatchProcessesChanged();
1763 case DISPATCH_PROCESS_DIED_UI_MSG: {
1764 final int pid = msg.arg1;
1765 final int uid = msg.arg2;
1766 dispatchProcessDied(pid, uid);
1769 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1770 dispatchUidsChanged();
1776 final class MainHandler extends Handler {
1777 public MainHandler(Looper looper) {
1778 super(looper, null, true);
1782 public void handleMessage(Message msg) {
1784 case UPDATE_CONFIGURATION_MSG: {
1785 final ContentResolver resolver = mContext.getContentResolver();
1786 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1789 case GC_BACKGROUND_PROCESSES_MSG: {
1790 synchronized (ActivityManagerService.this) {
1791 performAppGcsIfAppropriateLocked();
1794 case SERVICE_TIMEOUT_MSG: {
1797 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1799 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1802 mServices.serviceTimeout((ProcessRecord)msg.obj);
1804 case UPDATE_TIME_ZONE: {
1805 synchronized (ActivityManagerService.this) {
1806 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1807 ProcessRecord r = mLruProcesses.get(i);
1808 if (r.thread != null) {
1810 r.thread.updateTimeZone();
1811 } catch (RemoteException ex) {
1812 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1818 case CLEAR_DNS_CACHE_MSG: {
1819 synchronized (ActivityManagerService.this) {
1820 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1821 ProcessRecord r = mLruProcesses.get(i);
1822 if (r.thread != null) {
1824 r.thread.clearDnsCache();
1825 } catch (RemoteException ex) {
1826 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1832 case UPDATE_HTTP_PROXY_MSG: {
1833 ProxyInfo proxy = (ProxyInfo)msg.obj;
1836 String exclList = "";
1837 Uri pacFileUrl = Uri.EMPTY;
1838 if (proxy != null) {
1839 host = proxy.getHost();
1840 port = Integer.toString(proxy.getPort());
1841 exclList = proxy.getExclusionListAsString();
1842 pacFileUrl = proxy.getPacFileUrl();
1844 synchronized (ActivityManagerService.this) {
1845 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1846 ProcessRecord r = mLruProcesses.get(i);
1847 if (r.thread != null) {
1849 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1850 } catch (RemoteException ex) {
1851 Slog.w(TAG, "Failed to update http proxy for: " +
1852 r.info.processName);
1858 case PROC_START_TIMEOUT_MSG: {
1861 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1863 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1866 ProcessRecord app = (ProcessRecord)msg.obj;
1867 synchronized (ActivityManagerService.this) {
1868 processStartTimedOutLocked(app);
1871 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1872 ProcessRecord app = (ProcessRecord)msg.obj;
1873 synchronized (ActivityManagerService.this) {
1874 processContentProviderPublishTimedOutLocked(app);
1877 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1878 synchronized (ActivityManagerService.this) {
1879 mActivityStarter.doPendingActivityLaunchesLocked(true);
1882 case KILL_APPLICATION_MSG: {
1883 synchronized (ActivityManagerService.this) {
1884 final int appId = msg.arg1;
1885 final int userId = msg.arg2;
1886 Bundle bundle = (Bundle)msg.obj;
1887 String pkg = bundle.getString("pkg");
1888 String reason = bundle.getString("reason");
1889 forceStopPackageLocked(pkg, appId, false, false, true, false,
1890 false, userId, reason);
1893 case FINALIZE_PENDING_INTENT_MSG: {
1894 ((PendingIntentRecord)msg.obj).completeFinalize();
1896 case POST_HEAVY_NOTIFICATION_MSG: {
1897 INotificationManager inm = NotificationManager.getService();
1902 ActivityRecord root = (ActivityRecord)msg.obj;
1903 ProcessRecord process = root.app;
1904 if (process == null) {
1909 Context context = mContext.createPackageContext(process.info.packageName, 0);
1910 String text = mContext.getString(R.string.heavy_weight_notification,
1911 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1912 Notification notification = new Notification.Builder(context)
1913 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1917 .setColor(mContext.getColor(
1918 com.android.internal.R.color.system_notification_accent_color))
1919 .setContentTitle(text)
1921 mContext.getText(R.string.heavy_weight_notification_detail))
1922 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1923 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1924 new UserHandle(root.userId)))
1927 int[] outId = new int[1];
1928 inm.enqueueNotificationWithTag("android", "android", null,
1929 R.string.heavy_weight_notification,
1930 notification, outId, root.userId);
1931 } catch (RuntimeException e) {
1932 Slog.w(ActivityManagerService.TAG,
1933 "Error showing notification for heavy-weight app", e);
1934 } catch (RemoteException e) {
1936 } catch (NameNotFoundException e) {
1937 Slog.w(TAG, "Unable to create context for heavy notification", e);
1940 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1941 INotificationManager inm = NotificationManager.getService();
1946 inm.cancelNotificationWithTag("android", null,
1947 R.string.heavy_weight_notification, msg.arg1);
1948 } catch (RuntimeException e) {
1949 Slog.w(ActivityManagerService.TAG,
1950 "Error canceling notification for service", e);
1951 } catch (RemoteException e) {
1954 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1955 synchronized (ActivityManagerService.this) {
1956 checkExcessivePowerUsageLocked(true);
1957 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1958 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1959 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1962 case REPORT_MEM_USAGE_MSG: {
1963 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1964 Thread thread = new Thread() {
1965 @Override public void run() {
1966 reportMemUsage(memInfos);
1972 case REPORT_USER_SWITCH_MSG: {
1973 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1976 case CONTINUE_USER_SWITCH_MSG: {
1977 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1980 case USER_SWITCH_TIMEOUT_MSG: {
1981 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1984 case IMMERSIVE_MODE_LOCK_MSG: {
1985 final boolean nextState = (msg.arg1 != 0);
1986 if (mUpdateLock.isHeld() != nextState) {
1987 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1988 "Applying new update lock state '" + nextState
1989 + "' for " + (ActivityRecord)msg.obj);
1991 mUpdateLock.acquire();
1993 mUpdateLock.release();
1998 case PERSIST_URI_GRANTS_MSG: {
1999 writeGrantedUriPermissions();
2002 case REQUEST_ALL_PSS_MSG: {
2003 synchronized (ActivityManagerService.this) {
2004 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2008 case START_PROFILES_MSG: {
2009 synchronized (ActivityManagerService.this) {
2010 mUserController.startProfilesLocked();
2015 synchronized (ActivityManagerService.this) {
2016 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2017 ProcessRecord r = mLruProcesses.get(i);
2018 if (r.thread != null) {
2020 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2021 } catch (RemoteException ex) {
2022 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2029 case SYSTEM_USER_START_MSG: {
2030 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2031 Integer.toString(msg.arg1), msg.arg1);
2032 mSystemServiceManager.startUser(msg.arg1);
2035 case SYSTEM_USER_UNLOCK_MSG: {
2036 final int userId = msg.arg1;
2037 mSystemServiceManager.unlockUser(userId);
2038 synchronized (ActivityManagerService.this) {
2039 mRecentTasks.loadUserRecentsLocked(userId);
2041 if (userId == UserHandle.USER_SYSTEM) {
2042 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2044 installEncryptionUnawareProviders(userId);
2045 mUserController.finishUserUnlocked((UserState) msg.obj);
2048 case SYSTEM_USER_CURRENT_MSG: {
2049 mBatteryStatsService.noteEvent(
2050 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2051 Integer.toString(msg.arg2), msg.arg2);
2052 mBatteryStatsService.noteEvent(
2053 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2054 Integer.toString(msg.arg1), msg.arg1);
2055 mSystemServiceManager.switchUser(msg.arg1);
2058 case ENTER_ANIMATION_COMPLETE_MSG: {
2059 synchronized (ActivityManagerService.this) {
2060 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2061 if (r != null && r.app != null && r.app.thread != null) {
2063 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2064 } catch (RemoteException e) {
2070 case FINISH_BOOTING_MSG: {
2071 if (msg.arg1 != 0) {
2072 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2074 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2076 if (msg.arg2 != 0) {
2077 enableScreenAfterBoot();
2081 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2083 Locale l = (Locale) msg.obj;
2084 IBinder service = ServiceManager.getService("mount");
2085 IMountService mountService = IMountService.Stub.asInterface(service);
2086 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2087 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2088 } catch (RemoteException e) {
2089 Log.e(TAG, "Error storing locale for decryption UI", e);
2093 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2094 synchronized (ActivityManagerService.this) {
2095 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2097 // Make a one-way callback to the listener
2098 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2099 } catch (RemoteException e){
2100 // Handled by the RemoteCallbackList
2103 mTaskStackListeners.finishBroadcast();
2107 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2108 synchronized (ActivityManagerService.this) {
2109 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2111 // Make a one-way callback to the listener
2112 mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2113 } catch (RemoteException e){
2114 // Handled by the RemoteCallbackList
2117 mTaskStackListeners.finishBroadcast();
2121 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2122 synchronized (ActivityManagerService.this) {
2123 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2125 // Make a one-way callback to the listener
2126 mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2127 } catch (RemoteException e){
2128 // Handled by the RemoteCallbackList
2131 mTaskStackListeners.finishBroadcast();
2135 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2136 synchronized (ActivityManagerService.this) {
2137 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2139 // Make a one-way callback to the listener
2140 mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2141 } catch (RemoteException e){
2142 // Handled by the RemoteCallbackList
2145 mTaskStackListeners.finishBroadcast();
2149 case NOTIFY_FORCED_RESIZABLE_MSG: {
2150 synchronized (ActivityManagerService.this) {
2151 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2153 // Make a one-way callback to the listener
2154 mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2155 (String) msg.obj, msg.arg1);
2156 } catch (RemoteException e){
2157 // Handled by the RemoteCallbackList
2160 mTaskStackListeners.finishBroadcast();
2164 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2165 synchronized (ActivityManagerService.this) {
2166 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2168 // Make a one-way callback to the listener
2169 mTaskStackListeners.getBroadcastItem(i)
2170 .onActivityDismissingDockedStack();
2171 } catch (RemoteException e){
2172 // Handled by the RemoteCallbackList
2175 mTaskStackListeners.finishBroadcast();
2179 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2180 final int uid = msg.arg1;
2181 final byte[] firstPacket = (byte[]) msg.obj;
2183 synchronized (mPidsSelfLocked) {
2184 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2185 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2188 p.thread.notifyCleartextNetwork(firstPacket);
2189 } catch (RemoteException ignored) {
2196 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2197 final String procName;
2199 final long memLimit;
2200 final String reportPackage;
2201 synchronized (ActivityManagerService.this) {
2202 procName = mMemWatchDumpProcName;
2203 uid = mMemWatchDumpUid;
2204 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2206 val = mMemWatchProcesses.get(procName, 0);
2209 memLimit = val.first;
2210 reportPackage = val.second;
2213 reportPackage = null;
2216 if (procName == null) {
2220 if (DEBUG_PSS) Slog.d(TAG_PSS,
2221 "Showing dump heap notification from " + procName + "/" + uid);
2223 INotificationManager inm = NotificationManager.getService();
2228 String text = mContext.getString(R.string.dump_heap_notification, procName);
2231 Intent deleteIntent = new Intent();
2232 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2233 Intent intent = new Intent();
2234 intent.setClassName("android", DumpHeapActivity.class.getName());
2235 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2236 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2237 if (reportPackage != null) {
2238 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2240 int userId = UserHandle.getUserId(uid);
2241 Notification notification = new Notification.Builder(mContext)
2242 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2245 .setAutoCancel(true)
2247 .setColor(mContext.getColor(
2248 com.android.internal.R.color.system_notification_accent_color))
2249 .setContentTitle(text)
2251 mContext.getText(R.string.dump_heap_notification_detail))
2252 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2253 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2254 new UserHandle(userId)))
2255 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2256 deleteIntent, 0, UserHandle.SYSTEM))
2260 int[] outId = new int[1];
2261 inm.enqueueNotificationWithTag("android", "android", null,
2262 R.string.dump_heap_notification,
2263 notification, outId, userId);
2264 } catch (RuntimeException e) {
2265 Slog.w(ActivityManagerService.TAG,
2266 "Error showing notification for dump heap", e);
2267 } catch (RemoteException e) {
2270 case DELETE_DUMPHEAP_MSG: {
2271 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2272 DumpHeapActivity.JAVA_URI,
2273 Intent.FLAG_GRANT_READ_URI_PERMISSION
2274 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2275 UserHandle.myUserId());
2276 synchronized (ActivityManagerService.this) {
2277 mMemWatchDumpFile = null;
2278 mMemWatchDumpProcName = null;
2279 mMemWatchDumpPid = -1;
2280 mMemWatchDumpUid = -1;
2283 case FOREGROUND_PROFILE_CHANGED_MSG: {
2284 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2286 case REPORT_TIME_TRACKER_MSG: {
2287 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2288 tracker.deliverResult(mContext);
2290 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2291 mUserController.dispatchUserSwitchComplete(msg.arg1);
2293 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2294 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2296 connection.shutdown();
2297 } catch (RemoteException e) {
2298 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2300 // Only a UiAutomation can set this flag and now that
2301 // it is finished we make sure it is reset to its default.
2302 mUserIsMonkey = false;
2304 case APP_BOOST_DEACTIVATE_MSG: {
2305 synchronized(ActivityManagerService.this) {
2307 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2308 nativeMigrateFromBoost();
2310 mBoostStartTime = 0;
2312 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2313 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2318 case IDLE_UIDS_MSG: {
2321 case LOG_STACK_STATE: {
2322 synchronized (ActivityManagerService.this) {
2323 mStackSupervisor.logStackState();
2326 case VR_MODE_CHANGE_MSG: {
2327 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2328 if (vrService == null) {
2331 final ActivityRecord r = (ActivityRecord) msg.obj;
2333 ComponentName requestedPackage;
2334 ComponentName callingPackage;
2336 synchronized (ActivityManagerService.this) {
2337 vrMode = r.requestedVrComponent != null;
2338 requestedPackage = r.requestedVrComponent;
2340 callingPackage = r.info.getComponentName();
2341 if (mInVrMode != vrMode) {
2343 mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2344 if (r.app != null) {
2345 ProcessRecord proc = r.app;
2346 if (proc.vrThreadTid > 0) {
2347 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2349 if (mInVrMode == true) {
2350 Process.setThreadScheduler(proc.vrThreadTid,
2351 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2353 Process.setThreadScheduler(proc.vrThreadTid,
2354 Process.SCHED_OTHER, 0);
2356 } catch (IllegalArgumentException e) {
2357 Slog.w(TAG, "Failed to set scheduling policy, thread does"
2358 + " not exist:\n" + e);
2365 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2366 } case NOTIFY_VR_SLEEPING_MSG: {
2367 notifyVrManagerOfSleepState(msg.arg1 != 0);
2373 static final int COLLECT_PSS_BG_MSG = 1;
2375 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2377 public void handleMessage(Message msg) {
2379 case COLLECT_PSS_BG_MSG: {
2380 long start = SystemClock.uptimeMillis();
2381 MemInfoReader memInfo = null;
2382 synchronized (ActivityManagerService.this) {
2383 if (mFullPssPending) {
2384 mFullPssPending = false;
2385 memInfo = new MemInfoReader();
2388 if (memInfo != null) {
2389 updateCpuStatsNow();
2390 long nativeTotalPss = 0;
2391 final List<ProcessCpuTracker.Stats> stats;
2392 synchronized (mProcessCpuTracker) {
2393 stats = mProcessCpuTracker.getStats( (st)-> {
2394 return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2397 final int N = stats.size();
2398 for (int j = 0; j < N; j++) {
2399 synchronized (mPidsSelfLocked) {
2400 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2401 // This is one of our own processes; skip it.
2405 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2407 memInfo.readMemInfo();
2408 synchronized (ActivityManagerService.this) {
2409 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2410 + (SystemClock.uptimeMillis()-start) + "ms");
2411 final long cachedKb = memInfo.getCachedSizeKb();
2412 final long freeKb = memInfo.getFreeSizeKb();
2413 final long zramKb = memInfo.getZramTotalSizeKb();
2414 final long kernelKb = memInfo.getKernelUsedSizeKb();
2415 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2416 kernelKb*1024, nativeTotalPss*1024);
2417 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2423 long[] tmp = new long[2];
2429 synchronized (ActivityManagerService.this) {
2430 if (mPendingPssProcesses.size() <= 0) {
2431 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2432 "Collected PSS of " + num + " processes in "
2433 + (SystemClock.uptimeMillis() - start) + "ms");
2434 mPendingPssProcesses.clear();
2437 proc = mPendingPssProcesses.remove(0);
2438 procState = proc.pssProcState;
2439 lastPssTime = proc.lastPssTime;
2440 if (proc.thread != null && procState == proc.setProcState
2441 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2442 < SystemClock.uptimeMillis()) {
2450 long pss = Debug.getPss(pid, tmp, null);
2451 synchronized (ActivityManagerService.this) {
2452 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2453 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2455 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2456 SystemClock.uptimeMillis());
2466 public void setSystemProcess() {
2468 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2469 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2470 ServiceManager.addService("meminfo", new MemBinder(this));
2471 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2472 ServiceManager.addService("dbinfo", new DbBinder(this));
2473 if (MONITOR_CPU_USAGE) {
2474 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2476 ServiceManager.addService("permission", new PermissionController(this));
2477 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2479 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2480 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2481 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2483 synchronized (this) {
2484 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2485 app.persistent = true;
2487 app.maxAdj = ProcessList.SYSTEM_ADJ;
2488 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2489 synchronized (mPidsSelfLocked) {
2490 mPidsSelfLocked.put(app.pid, app);
2492 updateLruProcessLocked(app, false, null);
2493 updateOomAdjLocked();
2495 } catch (PackageManager.NameNotFoundException e) {
2496 throw new RuntimeException(
2497 "Unable to find android system package", e);
2501 public void setWindowManager(WindowManagerService wm) {
2502 mWindowManager = wm;
2503 mStackSupervisor.setWindowManager(wm);
2504 mActivityStarter.setWindowManager(wm);
2507 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2508 mUsageStatsService = usageStatsManager;
2511 public void startObservingNativeCrashes() {
2512 final NativeCrashListener ncl = new NativeCrashListener(this);
2516 public IAppOpsService getAppOpsService() {
2517 return mAppOpsService;
2520 static class MemBinder extends Binder {
2521 ActivityManagerService mActivityManagerService;
2522 MemBinder(ActivityManagerService activityManagerService) {
2523 mActivityManagerService = activityManagerService;
2527 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2528 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2529 != PackageManager.PERMISSION_GRANTED) {
2530 pw.println("Permission Denial: can't dump meminfo from from pid="
2531 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2532 + " without permission " + android.Manifest.permission.DUMP);
2536 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2540 static class GraphicsBinder extends Binder {
2541 ActivityManagerService mActivityManagerService;
2542 GraphicsBinder(ActivityManagerService activityManagerService) {
2543 mActivityManagerService = activityManagerService;
2547 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2548 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2549 != PackageManager.PERMISSION_GRANTED) {
2550 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2551 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2552 + " without permission " + android.Manifest.permission.DUMP);
2556 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2560 static class DbBinder extends Binder {
2561 ActivityManagerService mActivityManagerService;
2562 DbBinder(ActivityManagerService activityManagerService) {
2563 mActivityManagerService = activityManagerService;
2567 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2568 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2569 != PackageManager.PERMISSION_GRANTED) {
2570 pw.println("Permission Denial: can't dump dbinfo from from pid="
2571 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2572 + " without permission " + android.Manifest.permission.DUMP);
2576 mActivityManagerService.dumpDbInfo(fd, pw, args);
2580 static class CpuBinder extends Binder {
2581 ActivityManagerService mActivityManagerService;
2582 CpuBinder(ActivityManagerService activityManagerService) {
2583 mActivityManagerService = activityManagerService;
2587 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2588 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2589 != PackageManager.PERMISSION_GRANTED) {
2590 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2591 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2592 + " without permission " + android.Manifest.permission.DUMP);
2596 synchronized (mActivityManagerService.mProcessCpuTracker) {
2597 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2598 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2599 SystemClock.uptimeMillis()));
2604 public static final class Lifecycle extends SystemService {
2605 private final ActivityManagerService mService;
2607 public Lifecycle(Context context) {
2609 mService = new ActivityManagerService(context);
2613 public void onStart() {
2617 public ActivityManagerService getService() {
2622 // Note: This method is invoked on the main thread but may need to attach various
2623 // handlers to other threads. So take care to be explicit about the looper.
2624 public ActivityManagerService(Context systemContext) {
2625 mContext = systemContext;
2626 mFactoryTest = FactoryTest.getMode();
2627 mSystemThread = ActivityThread.currentActivityThread();
2629 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2631 mPermissionReviewRequired = mContext.getResources().getBoolean(
2632 com.android.internal.R.bool.config_permissionReviewRequired);
2634 mHandlerThread = new ServiceThread(TAG,
2635 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2636 mHandlerThread.start();
2637 mHandler = new MainHandler(mHandlerThread.getLooper());
2638 mUiHandler = new UiHandler();
2640 /* static; one-time init here */
2641 if (sKillHandler == null) {
2642 sKillThread = new ServiceThread(TAG + ":kill",
2643 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2644 sKillThread.start();
2645 sKillHandler = new KillHandler(sKillThread.getLooper());
2648 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2649 "foreground", BROADCAST_FG_TIMEOUT, false);
2650 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2651 "background", BROADCAST_BG_TIMEOUT, true);
2652 mBroadcastQueues[0] = mFgBroadcastQueue;
2653 mBroadcastQueues[1] = mBgBroadcastQueue;
2655 mServices = new ActiveServices(this);
2656 mProviderMap = new ProviderMap(this);
2657 mAppErrors = new AppErrors(mContext, this);
2659 // TODO: Move creation of battery stats service outside of activity manager service.
2660 File dataDir = Environment.getDataDirectory();
2661 File systemDir = new File(dataDir, "system");
2663 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2664 mBatteryStatsService.getActiveStatistics().readLocked();
2665 mBatteryStatsService.scheduleWriteToDisk();
2666 mOnBattery = DEBUG_POWER ? true
2667 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2668 mBatteryStatsService.getActiveStatistics().setCallback(this);
2670 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2672 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2673 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2674 new IAppOpsCallback.Stub() {
2675 @Override public void opChanged(int op, int uid, String packageName) {
2676 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2677 if (mAppOpsService.checkOperation(op, uid, packageName)
2678 != AppOpsManager.MODE_ALLOWED) {
2679 runInBackgroundDisabled(uid);
2685 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2687 mUserController = new UserController(this);
2689 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2690 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2692 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2693 mUseFifoUiScheduling = true;
2696 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2698 mConfiguration.setToDefaults();
2699 mConfiguration.setLocales(LocaleList.getDefault());
2701 mConfigurationSeq = mConfiguration.seq = 1;
2702 mProcessCpuTracker.init();
2704 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2705 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2706 mStackSupervisor = new ActivityStackSupervisor(this);
2707 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2708 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2710 mProcessCpuThread = new Thread("CpuTracker") {
2716 synchronized(this) {
2717 final long now = SystemClock.uptimeMillis();
2718 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2719 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2720 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2721 // + ", write delay=" + nextWriteDelay);
2722 if (nextWriteDelay < nextCpuDelay) {
2723 nextCpuDelay = nextWriteDelay;
2725 if (nextCpuDelay > 0) {
2726 mProcessCpuMutexFree.set(true);
2727 this.wait(nextCpuDelay);
2730 } catch (InterruptedException e) {
2732 updateCpuStatsNow();
2733 } catch (Exception e) {
2734 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2740 Watchdog.getInstance().addMonitor(this);
2741 Watchdog.getInstance().addThread(mHandler);
2744 public void setSystemServiceManager(SystemServiceManager mgr) {
2745 mSystemServiceManager = mgr;
2748 public void setInstaller(Installer installer) {
2749 mInstaller = installer;
2752 private void start() {
2753 Process.removeAllProcessGroups();
2754 mProcessCpuThread.start();
2756 mBatteryStatsService.publish(mContext);
2757 mAppOpsService.publish(mContext);
2758 Slog.d("AppOps", "AppOpsService published");
2759 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2762 void onUserStoppedLocked(int userId) {
2763 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2766 public void initPowerManagement() {
2767 mStackSupervisor.initPowerManagement();
2768 mBatteryStatsService.initPowerManagement();
2769 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2770 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2771 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2772 mVoiceWakeLock.setReferenceCounted(false);
2776 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2777 throws RemoteException {
2778 if (code == SYSPROPS_TRANSACTION) {
2779 // We need to tell all apps about the system property change.
2780 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2781 synchronized(this) {
2782 final int NP = mProcessNames.getMap().size();
2783 for (int ip=0; ip<NP; ip++) {
2784 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2785 final int NA = apps.size();
2786 for (int ia=0; ia<NA; ia++) {
2787 ProcessRecord app = apps.valueAt(ia);
2788 if (app.thread != null) {
2789 procs.add(app.thread.asBinder());
2795 int N = procs.size();
2796 for (int i=0; i<N; i++) {
2797 Parcel data2 = Parcel.obtain();
2799 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2800 } catch (RemoteException e) {
2806 return super.onTransact(code, data, reply, flags);
2807 } catch (RuntimeException e) {
2808 // The activity manager only throws security exceptions, so let's
2810 if (!(e instanceof SecurityException)) {
2811 Slog.wtf(TAG, "Activity Manager Crash", e);
2817 void updateCpuStats() {
2818 final long now = SystemClock.uptimeMillis();
2819 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2822 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2823 synchronized (mProcessCpuThread) {
2824 mProcessCpuThread.notify();
2829 void updateCpuStatsNow() {
2830 synchronized (mProcessCpuTracker) {
2831 mProcessCpuMutexFree.set(false);
2832 final long now = SystemClock.uptimeMillis();
2833 boolean haveNewCpuStats = false;
2835 if (MONITOR_CPU_USAGE &&
2836 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2837 mLastCpuTime.set(now);
2838 mProcessCpuTracker.update();
2839 if (mProcessCpuTracker.hasGoodLastStats()) {
2840 haveNewCpuStats = true;
2841 //Slog.i(TAG, mProcessCpu.printCurrentState());
2842 //Slog.i(TAG, "Total CPU usage: "
2843 // + mProcessCpu.getTotalCpuPercent() + "%");
2845 // Slog the cpu usage if the property is set.
2846 if ("true".equals(SystemProperties.get("events.cpu"))) {
2847 int user = mProcessCpuTracker.getLastUserTime();
2848 int system = mProcessCpuTracker.getLastSystemTime();
2849 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2850 int irq = mProcessCpuTracker.getLastIrqTime();
2851 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2852 int idle = mProcessCpuTracker.getLastIdleTime();
2854 int total = user + system + iowait + irq + softIrq + idle;
2855 if (total == 0) total = 1;
2857 EventLog.writeEvent(EventLogTags.CPU,
2858 ((user+system+iowait+irq+softIrq) * 100) / total,
2859 (user * 100) / total,
2860 (system * 100) / total,
2861 (iowait * 100) / total,
2862 (irq * 100) / total,
2863 (softIrq * 100) / total);
2868 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2869 synchronized(bstats) {
2870 synchronized(mPidsSelfLocked) {
2871 if (haveNewCpuStats) {
2872 if (bstats.startAddingCpuLocked()) {
2875 final int N = mProcessCpuTracker.countStats();
2876 for (int i=0; i<N; i++) {
2877 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2881 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2882 totalUTime += st.rel_utime;
2883 totalSTime += st.rel_stime;
2885 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2886 if (ps == null || !ps.isActive()) {
2887 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2888 pr.info.uid, pr.processName);
2890 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2891 pr.curCpuTime += st.rel_utime + st.rel_stime;
2893 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2894 if (ps == null || !ps.isActive()) {
2895 st.batteryStats = ps = bstats.getProcessStatsLocked(
2896 bstats.mapUid(st.uid), st.name);
2898 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2901 final int userTime = mProcessCpuTracker.getLastUserTime();
2902 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2903 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2904 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2905 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2906 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2907 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2908 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2913 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2914 mLastWriteTime = now;
2915 mBatteryStatsService.scheduleWriteToDisk();
2922 public void batteryNeedsCpuUpdate() {
2923 updateCpuStatsNow();
2927 public void batteryPowerChanged(boolean onBattery) {
2928 // When plugging in, update the CPU stats first before changing
2930 updateCpuStatsNow();
2931 synchronized (this) {
2932 synchronized(mPidsSelfLocked) {
2933 mOnBattery = DEBUG_POWER ? true : onBattery;
2939 public void batterySendBroadcast(Intent intent) {
2940 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2941 AppOpsManager.OP_NONE, null, false, false,
2942 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2946 * Initialize the application bind args. These are passed to each
2947 * process when the bindApplication() IPC is sent to the process. They're
2948 * lazily setup to make sure the services are running when they're asked for.
2950 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2951 // Isolated processes won't get this optimization, so that we don't
2952 // violate the rules about which services they have access to.
2954 if (mIsolatedAppBindArgs == null) {
2955 mIsolatedAppBindArgs = new HashMap<>();
2956 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2958 return mIsolatedAppBindArgs;
2961 if (mAppBindArgs == null) {
2962 mAppBindArgs = new HashMap<>();
2964 // Setup the application init args
2965 mAppBindArgs.put("package", ServiceManager.getService("package"));
2966 mAppBindArgs.put("window", ServiceManager.getService("window"));
2967 mAppBindArgs.put(Context.ALARM_SERVICE,
2968 ServiceManager.getService(Context.ALARM_SERVICE));
2970 return mAppBindArgs;
2973 boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2974 if (r == null || mFocusedActivity == r) {
2978 if (!r.isFocusable()) {
2979 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2983 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2985 final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2986 if (wasDoingSetFocusedActivity) Slog.w(TAG,
2987 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2988 mDoingSetFocusedActivity = true;
2990 final ActivityRecord last = mFocusedActivity;
2991 mFocusedActivity = r;
2992 if (r.task.isApplicationTask()) {
2993 if (mCurAppTimeTracker != r.appTimeTracker) {
2994 // We are switching app tracking. Complete the current one.
2995 if (mCurAppTimeTracker != null) {
2996 mCurAppTimeTracker.stop();
2997 mHandler.obtainMessage(
2998 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2999 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3000 mCurAppTimeTracker = null;
3002 if (r.appTimeTracker != null) {
3003 mCurAppTimeTracker = r.appTimeTracker;
3004 startTimeTrackingFocusedActivityLocked();
3007 startTimeTrackingFocusedActivityLocked();
3010 r.appTimeTracker = null;
3012 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3013 // TODO: Probably not, because we don't want to resume voice on switching
3014 // back to this activity
3015 if (r.task.voiceInteractor != null) {
3016 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3018 finishRunningVoiceLocked();
3019 IVoiceInteractionSession session;
3020 if (last != null && ((session = last.task.voiceSession) != null
3021 || (session = last.voiceSession) != null)) {
3022 // We had been in a voice interaction session, but now focused has
3023 // move to something different. Just finish the session, we can't
3024 // return to it and retain the proper state and synchronization with
3025 // the voice interaction service.
3026 finishVoiceTask(session);
3029 if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3030 mWindowManager.setFocusedApp(r.appToken, true);
3032 applyUpdateLockStateLocked(r);
3033 applyUpdateVrModeLocked(r);
3034 if (mFocusedActivity.userId != mLastFocusedUserId) {
3035 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3036 mHandler.obtainMessage(
3037 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3038 mLastFocusedUserId = mFocusedActivity.userId;
3041 // Log a warning if the focused app is changed during the process. This could
3042 // indicate a problem of the focus setting logic!
3043 if (mFocusedActivity != r) Slog.w(TAG,
3044 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3045 mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3047 EventLogTags.writeAmFocusedActivity(
3048 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3049 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3054 final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3055 if (mFocusedActivity != goingAway) {
3059 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3060 if (focusedStack != null) {
3061 final ActivityRecord top = focusedStack.topActivity();
3062 if (top != null && top.userId != mLastFocusedUserId) {
3063 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3064 mHandler.sendMessage(
3065 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3066 mLastFocusedUserId = top.userId;
3070 // Try to move focus to another activity if possible.
3071 if (setFocusedActivityLocked(
3072 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3076 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3077 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3078 mFocusedActivity = null;
3079 EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3083 public void setFocusedStack(int stackId) {
3084 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3085 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3086 final long callingId = Binder.clearCallingIdentity();
3088 synchronized (this) {
3089 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3090 if (stack == null) {
3093 final ActivityRecord r = stack.topRunningActivityLocked();
3094 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3095 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3099 Binder.restoreCallingIdentity(callingId);
3104 public void setFocusedTask(int taskId) {
3105 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3106 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3107 final long callingId = Binder.clearCallingIdentity();
3109 synchronized (this) {
3110 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3114 if (mUserController.shouldConfirmCredentials(task.userId)) {
3115 mActivityStarter.showConfirmDeviceCredential(task.userId);
3116 if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3117 mStackSupervisor.moveTaskToStackLocked(task.taskId,
3118 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3119 "setFocusedTask", ANIMATE);
3123 final ActivityRecord r = task.topRunningActivityLocked();
3124 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3125 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3129 Binder.restoreCallingIdentity(callingId);
3133 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3135 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3136 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3137 synchronized (this) {
3138 if (listener != null) {
3139 mTaskStackListeners.register(listener);
3145 public void notifyActivityDrawn(IBinder token) {
3146 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3147 synchronized (this) {
3148 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3150 r.task.stack.notifyActivityDrawnLocked(r);
3155 final void applyUpdateLockStateLocked(ActivityRecord r) {
3156 // Modifications to the UpdateLock state are done on our handler, outside
3157 // the activity manager's locks. The new state is determined based on the
3158 // state *now* of the relevant activity record. The object is passed to
3159 // the handler solely for logging detail, not to be consulted/modified.
3160 final boolean nextState = r != null && r.immersive;
3161 mHandler.sendMessage(
3162 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3165 final void applyUpdateVrModeLocked(ActivityRecord r) {
3166 mHandler.sendMessage(
3167 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3170 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3171 mHandler.sendMessage(
3172 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3175 private void notifyVrManagerOfSleepState(boolean isSleeping) {
3176 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3177 if (vrService == null) {
3180 vrService.onSleepStateChanged(isSleeping);
3183 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3184 Message msg = Message.obtain();
3185 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3186 msg.obj = r.task.askedCompatMode ? null : r;
3187 mUiHandler.sendMessage(msg);
3190 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3191 if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3192 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3193 final Message msg = Message.obtain();
3194 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3196 mUiHandler.sendMessage(msg);
3200 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3201 String what, Object obj, ProcessRecord srcApp) {
3202 app.lastActivityTime = now;
3204 if (app.activities.size() > 0) {
3205 // Don't want to touch dependent processes that are hosting activities.
3209 int lrui = mLruProcesses.lastIndexOf(app);
3211 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3212 + what + " " + obj + " from " + srcApp);
3216 if (lrui >= index) {
3217 // Don't want to cause this to move dependent processes *back* in the
3218 // list as if they were less frequently used.
3222 if (lrui >= mLruProcessActivityStart) {
3223 // Don't want to touch dependent processes that are hosting activities.
3227 mLruProcesses.remove(lrui);
3231 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3232 + " in LRU list: " + app);
3233 mLruProcesses.add(index, app);
3237 static void killProcessGroup(int uid, int pid) {
3238 if (sKillHandler != null) {
3239 sKillHandler.sendMessage(
3240 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3242 Slog.w(TAG, "Asked to kill process group before system bringup!");
3243 Process.killProcessGroup(uid, pid);
3247 final void removeLruProcessLocked(ProcessRecord app) {
3248 int lrui = mLruProcesses.lastIndexOf(app);
3251 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3252 Process.killProcessQuiet(app.pid);
3253 killProcessGroup(app.uid, app.pid);
3255 if (lrui <= mLruProcessActivityStart) {
3256 mLruProcessActivityStart--;
3258 if (lrui <= mLruProcessServiceStart) {
3259 mLruProcessServiceStart--;
3261 mLruProcesses.remove(lrui);
3265 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3266 ProcessRecord client) {
3267 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3268 || app.treatLikeActivity;
3269 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3270 if (!activityChange && hasActivity) {
3271 // The process has activities, so we are only allowing activity-based adjustments
3272 // to move it. It should be kept in the front of the list with other
3273 // processes that have activities, and we don't want those to change their
3274 // order except due to activity operations.
3279 final long now = SystemClock.uptimeMillis();
3280 app.lastActivityTime = now;
3282 // First a quick reject: if the app is already at the position we will
3283 // put it, then there is nothing to do.
3285 final int N = mLruProcesses.size();
3286 if (N > 0 && mLruProcesses.get(N-1) == app) {
3287 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3291 if (mLruProcessServiceStart > 0
3292 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3293 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3298 int lrui = mLruProcesses.lastIndexOf(app);
3300 if (app.persistent && lrui >= 0) {
3301 // We don't care about the position of persistent processes, as long as
3302 // they are in the list.
3303 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3307 /* In progress: compute new position first, so we can avoid doing work
3308 if the process is not actually going to move. Not yet working.
3311 boolean inActivity = false, inService = false;
3313 // Process has activities, put it at the very tipsy-top.
3314 addIndex = mLruProcesses.size();
3315 nextIndex = mLruProcessServiceStart;
3317 } else if (hasService) {
3318 // Process has services, put it at the top of the service list.
3319 addIndex = mLruProcessActivityStart;
3320 nextIndex = mLruProcessServiceStart;
3324 // Process not otherwise of interest, it goes to the top of the non-service area.
3325 addIndex = mLruProcessServiceStart;
3326 if (client != null) {
3327 int clientIndex = mLruProcesses.lastIndexOf(client);
3328 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3330 if (clientIndex >= 0 && addIndex > clientIndex) {
3331 addIndex = clientIndex;
3334 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3337 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3338 + mLruProcessActivityStart + "): " + app);
3342 if (lrui < mLruProcessActivityStart) {
3343 mLruProcessActivityStart--;
3345 if (lrui < mLruProcessServiceStart) {
3346 mLruProcessServiceStart--;
3349 if (addIndex > lrui) {
3352 if (nextIndex > lrui) {
3356 mLruProcesses.remove(lrui);
3360 mLruProcesses.add(addIndex, app);
3362 mLruProcessActivityStart++;
3365 mLruProcessActivityStart++;
3371 final int N = mLruProcesses.size();
3372 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3373 // Process doesn't have activities, but has clients with
3374 // activities... move it up, but one below the top (the top
3375 // should always have a real activity).
3376 if (DEBUG_LRU) Slog.d(TAG_LRU,
3377 "Adding to second-top of LRU activity list: " + app);
3378 mLruProcesses.add(N - 1, app);
3379 // To keep it from spamming the LRU list (by making a bunch of clients),
3380 // we will push down any other entries owned by the app.
3381 final int uid = app.info.uid;
3382 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3383 ProcessRecord subProc = mLruProcesses.get(i);
3384 if (subProc.info.uid == uid) {
3385 // We want to push this one down the list. If the process after
3386 // it is for the same uid, however, don't do so, because we don't
3387 // want them internally to be re-ordered.
3388 if (mLruProcesses.get(i - 1).info.uid != uid) {
3389 if (DEBUG_LRU) Slog.d(TAG_LRU,
3390 "Pushing uid " + uid + " swapping at " + i + ": "
3391 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3392 ProcessRecord tmp = mLruProcesses.get(i);
3393 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3394 mLruProcesses.set(i - 1, tmp);
3398 // A gap, we can stop here.
3403 // Process has activities, put it at the very tipsy-top.
3404 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3405 mLruProcesses.add(app);
3407 nextIndex = mLruProcessServiceStart;
3408 } else if (hasService) {
3409 // Process has services, put it at the top of the service list.
3410 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3411 mLruProcesses.add(mLruProcessActivityStart, app);
3412 nextIndex = mLruProcessServiceStart;
3413 mLruProcessActivityStart++;
3415 // Process not otherwise of interest, it goes to the top of the non-service area.
3416 int index = mLruProcessServiceStart;
3417 if (client != null) {
3418 // If there is a client, don't allow the process to be moved up higher
3419 // in the list than that client.
3420 int clientIndex = mLruProcesses.lastIndexOf(client);
3421 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3422 + " when updating " + app);
3423 if (clientIndex <= lrui) {
3424 // Don't allow the client index restriction to push it down farther in the
3425 // list than it already is.
3428 if (clientIndex >= 0 && index > clientIndex) {
3429 index = clientIndex;
3432 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3433 mLruProcesses.add(index, app);
3434 nextIndex = index-1;
3435 mLruProcessActivityStart++;
3436 mLruProcessServiceStart++;
3439 // If the app is currently using a content provider or service,
3440 // bump those processes as well.
3441 for (int j=app.connections.size()-1; j>=0; j--) {
3442 ConnectionRecord cr = app.connections.valueAt(j);
3443 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3444 && cr.binding.service.app != null
3445 && cr.binding.service.app.lruSeq != mLruSeq
3446 && !cr.binding.service.app.persistent) {
3447 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3448 "service connection", cr, app);
3451 for (int j=app.conProviders.size()-1; j>=0; j--) {
3452 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3453 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3454 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3455 "provider reference", cpr, app);
3460 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3461 if (uid == Process.SYSTEM_UID) {
3462 // The system gets to run in any process. If there are multiple
3463 // processes with the same uid, just pick the first (this
3464 // should never happen).
3465 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3466 if (procs == null) return null;
3467 final int procCount = procs.size();
3468 for (int i = 0; i < procCount; i++) {
3469 final int procUid = procs.keyAt(i);
3470 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3471 // Don't use an app process or different user process for system component.
3474 return procs.valueAt(i);
3477 ProcessRecord proc = mProcessNames.get(processName, uid);
3478 if (false && proc != null && !keepIfLarge
3479 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3480 && proc.lastCachedPss >= 4000) {
3481 // Turn this condition on to cause killing to happen regularly, for testing.
3482 if (proc.baseProcessTracker != null) {
3483 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3485 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3486 } else if (proc != null && !keepIfLarge
3487 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3488 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3489 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3490 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3491 if (proc.baseProcessTracker != null) {
3492 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3494 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3500 void notifyPackageUse(String packageName, int reason) {
3501 IPackageManager pm = AppGlobals.getPackageManager();
3503 pm.notifyPackageUse(packageName, reason);
3504 } catch (RemoteException e) {
3508 boolean isNextTransitionForward() {
3509 int transit = mWindowManager.getPendingAppTransition();
3510 return transit == TRANSIT_ACTIVITY_OPEN
3511 || transit == TRANSIT_TASK_OPEN
3512 || transit == TRANSIT_TASK_TO_FRONT;
3515 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3516 String processName, String abiOverride, int uid, Runnable crashHandler) {
3517 synchronized(this) {
3518 ApplicationInfo info = new ApplicationInfo();
3519 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3520 // For isolated processes, the former contains the parent's uid and the latter the
3521 // actual uid of the isolated process.
3522 // In the special case introduced by this method (which is, starting an isolated
3523 // process directly from the SystemServer without an actual parent app process) the
3524 // closest thing to a parent's uid is SYSTEM_UID.
3525 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3526 // the |isolated| logic in the ProcessRecord constructor.
3527 info.uid = Process.SYSTEM_UID;
3528 info.processName = processName;
3529 info.className = entryPoint;
3530 info.packageName = "android";
3531 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3532 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3533 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3534 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3536 return proc != null ? proc.pid : 0;
3540 final ProcessRecord startProcessLocked(String processName,
3541 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3542 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3543 boolean isolated, boolean keepIfLarge) {
3544 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3545 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3546 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3547 null /* crashHandler */);
3550 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3551 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3552 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3553 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3554 long startTime = SystemClock.elapsedRealtime();
3557 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3558 checkTime(startTime, "startProcess: after getProcessRecord");
3560 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3561 // If we are in the background, then check to see if this process
3562 // is bad. If so, we will just silently fail.
3563 if (mAppErrors.isBadProcessLocked(info)) {
3564 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3565 + "/" + info.processName);
3569 // When the user is explicitly starting a process, then clear its
3570 // crash count so that we won't make it bad until they see at
3571 // least one crash dialog again, and make the process good again
3572 // if it had been bad.
3573 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3574 + "/" + info.processName);
3575 mAppErrors.resetProcessCrashTimeLocked(info);
3576 if (mAppErrors.isBadProcessLocked(info)) {
3577 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3578 UserHandle.getUserId(info.uid), info.uid,
3580 mAppErrors.clearBadProcessLocked(info);
3587 // If this is an isolated process, it can't re-use an existing process.
3591 // app launch boost for big.little configurations
3592 // use cpusets to migrate freshly launched tasks to big cores
3593 nativeMigrateToBoost();
3595 mBoostStartTime = SystemClock.uptimeMillis();
3596 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3597 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3599 // We don't have to do anything more if:
3600 // (1) There is an existing application record; and
3601 // (2) The caller doesn't think it is dead, OR there is no thread
3602 // object attached to it so we know it couldn't have crashed; and
3603 // (3) There is a pid assigned to it, so it is either starting or
3605 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3606 + " app=" + app + " knownToBeDead=" + knownToBeDead
3607 + " thread=" + (app != null ? app.thread : null)
3608 + " pid=" + (app != null ? app.pid : -1));
3609 if (app != null && app.pid > 0) {
3610 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3611 // We already have the app running, or are waiting for it to
3612 // come up (we have a pid but not yet its thread), so keep it.
3613 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3614 // If this is a new package in the process, add the package to the list
3615 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3616 checkTime(startTime, "startProcess: done, added package to proc");
3620 // An application record is attached to a previous process,
3622 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3623 checkTime(startTime, "startProcess: bad proc running, killing");
3624 killProcessGroup(app.uid, app.pid);
3625 handleAppDiedLocked(app, true, true);
3626 checkTime(startTime, "startProcess: done killing old proc");
3629 String hostingNameStr = hostingName != null
3630 ? hostingName.flattenToShortString() : null;
3633 checkTime(startTime, "startProcess: creating new process record");
3634 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3636 Slog.w(TAG, "Failed making new process record for "
3637 + processName + "/" + info.uid + " isolated=" + isolated);
3640 app.crashHandler = crashHandler;
3641 checkTime(startTime, "startProcess: done creating new process record");
3643 // If this is a new package in the process, add the package to the list
3644 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3645 checkTime(startTime, "startProcess: added package to existing proc");
3648 // If the system is not ready yet, then hold off on starting this
3649 // process until it is.
3650 if (!mProcessesReady
3651 && !isAllowedWhileBooting(info)
3652 && !allowWhileBooting) {
3653 if (!mProcessesOnHold.contains(app)) {
3654 mProcessesOnHold.add(app);
3656 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3657 "System not ready, putting on hold: " + app);
3658 checkTime(startTime, "startProcess: returning with proc on hold");
3662 checkTime(startTime, "startProcess: stepping in to startProcess");
3664 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3665 checkTime(startTime, "startProcess: done starting proc!");
3666 return (app.pid != 0) ? app : null;
3669 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3670 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3673 private final void startProcessLocked(ProcessRecord app,
3674 String hostingType, String hostingNameStr) {
3675 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3676 null /* entryPoint */, null /* entryPointArgs */);
3679 private final void startProcessLocked(ProcessRecord app, String hostingType,
3680 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3681 long startTime = SystemClock.elapsedRealtime();
3682 if (app.pid > 0 && app.pid != MY_PID) {
3683 checkTime(startTime, "startProcess: removing from pids map");
3684 synchronized (mPidsSelfLocked) {
3685 mPidsSelfLocked.remove(app.pid);
3686 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3688 checkTime(startTime, "startProcess: done removing from pids map");
3692 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3693 "startProcessLocked removing on hold: " + app);
3694 mProcessesOnHold.remove(app);
3696 checkTime(startTime, "startProcess: starting to update cpu stats");
3698 checkTime(startTime, "startProcess: done updating cpu stats");
3702 final int userId = UserHandle.getUserId(app.uid);
3703 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3704 } catch (RemoteException e) {
3705 throw e.rethrowAsRuntimeException();
3710 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3711 if (!app.isolated) {
3712 int[] permGids = null;
3714 checkTime(startTime, "startProcess: getting gids from package manager");
3715 final IPackageManager pm = AppGlobals.getPackageManager();
3716 permGids = pm.getPackageGids(app.info.packageName,
3717 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3718 MountServiceInternal mountServiceInternal = LocalServices.getService(
3719 MountServiceInternal.class);
3720 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3721 app.info.packageName);
3722 } catch (RemoteException e) {
3723 throw e.rethrowAsRuntimeException();
3727 * Add shared application and profile GIDs so applications can share some
3728 * resources like shared libraries and access user-wide resources
3730 if (ArrayUtils.isEmpty(permGids)) {
3733 gids = new int[permGids.length + 2];
3734 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3736 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3737 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3739 checkTime(startTime, "startProcess: building args");
3740 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3741 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3742 && mTopComponent != null
3743 && app.processName.equals(mTopComponent.getPackageName())) {
3746 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3747 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3752 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3753 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3754 // Also turn on CheckJNI for debuggable apps. It's quite
3755 // awkward to turn on otherwise.
3756 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3758 // Run the app in safe mode if its manifest requests so or the
3759 // system is booted in safe mode.
3760 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3761 mSafeMode == true) {
3762 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3764 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3765 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3767 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3768 if ("true".equals(genDebugInfoProperty)) {
3769 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3771 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3772 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3774 if ("1".equals(SystemProperties.get("debug.assert"))) {
3775 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3777 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3778 // Enable all debug flags required by the native debugger.
3779 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3780 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3781 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3782 mNativeDebuggingApp = null;
3785 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3786 if (requiredAbi == null) {
3787 requiredAbi = Build.SUPPORTED_ABIS[0];
3790 String instructionSet = null;
3791 if (app.info.primaryCpuAbi != null) {
3792 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3796 app.requiredAbi = requiredAbi;
3797 app.instructionSet = instructionSet;
3799 // Start the process. It will either succeed and return a result containing
3800 // the PID of the new process, or else throw a RuntimeException.
3801 boolean isActivityProcess = (entryPoint == null);
3802 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3803 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3805 checkTime(startTime, "startProcess: asking zygote to start proc");
3806 Process.ProcessStartResult startResult = Process.start(entryPoint,
3807 app.processName, uid, uid, gids, debugFlags, mountExternal,
3808 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3809 app.info.dataDir, entryPointArgs);
3810 checkTime(startTime, "startProcess: returned from zygote!");
3811 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3813 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3814 checkTime(startTime, "startProcess: done updating battery stats");
3816 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3817 UserHandle.getUserId(uid), startResult.pid, uid,
3818 app.processName, hostingType,
3819 hostingNameStr != null ? hostingNameStr : "");
3822 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3823 app.info.seinfo, app.info.sourceDir, startResult.pid);
3824 } catch (RemoteException ex) {
3828 if (app.persistent) {
3829 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3832 checkTime(startTime, "startProcess: building log message");
3833 StringBuilder buf = mStringBuilder;
3835 buf.append("Start proc ");
3836 buf.append(startResult.pid);
3838 buf.append(app.processName);
3840 UserHandle.formatUid(buf, uid);
3841 if (!isActivityProcess) {
3843 buf.append(entryPoint);
3846 buf.append(" for ");
3847 buf.append(hostingType);
3848 if (hostingNameStr != null) {
3850 buf.append(hostingNameStr);
3852 Slog.i(TAG, buf.toString());
3853 app.setPid(startResult.pid);
3854 app.usingWrapper = startResult.usingWrapper;
3855 app.removed = false;
3857 app.killedByAm = false;
3858 checkTime(startTime, "startProcess: starting to update pids map");
3859 ProcessRecord oldApp;
3860 synchronized (mPidsSelfLocked) {
3861 oldApp = mPidsSelfLocked.get(startResult.pid);
3863 // If there is already an app occupying that pid that hasn't been cleaned up
3864 if (oldApp != null && !app.isolated) {
3865 // Clean up anything relating to this pid first
3866 Slog.w(TAG, "Reusing pid " + startResult.pid
3867 + " while app is still mapped to it");
3868 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3869 true /*replacingPid*/);
3871 synchronized (mPidsSelfLocked) {
3872 this.mPidsSelfLocked.put(startResult.pid, app);
3873 if (isActivityProcess) {
3874 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3876 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3877 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3880 checkTime(startTime, "startProcess: done updating pids map");
3881 } catch (RuntimeException e) {
3882 Slog.e(TAG, "Failure starting process " + app.processName, e);
3884 // Something went very wrong while trying to start this process; one
3885 // common case is when the package is frozen due to an active
3886 // upgrade. To recover, clean up any active bookkeeping related to
3887 // starting this process. (We already invoked this method once when
3888 // the package was initially frozen through KILL_APPLICATION_MSG, so
3889 // it doesn't hurt to use it again.)
3890 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3891 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3895 void updateUsageStats(ActivityRecord component, boolean resumed) {
3896 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3897 "updateUsageStats: comp=" + component + "res=" + resumed);
3898 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3900 if (mUsageStatsService != null) {
3901 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902 UsageEvents.Event.MOVE_TO_FOREGROUND);
3904 synchronized (stats) {
3905 stats.noteActivityResumedLocked(component.app.uid);
3908 if (mUsageStatsService != null) {
3909 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3910 UsageEvents.Event.MOVE_TO_BACKGROUND);
3912 synchronized (stats) {
3913 stats.noteActivityPausedLocked(component.app.uid);
3918 Intent getHomeIntent() {
3919 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3920 intent.setComponent(mTopComponent);
3921 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3922 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3923 intent.addCategory(Intent.CATEGORY_HOME);
3928 boolean startHomeActivityLocked(int userId, String reason) {
3929 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3930 && mTopAction == null) {
3931 // We are running in factory test mode, but unable to find
3932 // the factory test app, so just sit around displaying the
3933 // error message and don't try to start anything.
3936 Intent intent = getHomeIntent();
3937 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3938 if (aInfo != null) {
3939 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3940 // Don't do this if the home app is currently being
3942 aInfo = new ActivityInfo(aInfo);
3943 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3944 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3945 aInfo.applicationInfo.uid, true);
3946 if (app == null || app.instrumentationClass == null) {
3947 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3948 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3951 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3957 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3958 ActivityInfo ai = null;
3959 ComponentName comp = intent.getComponent();
3963 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3965 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3967 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3971 ai = info.activityInfo;
3974 } catch (RemoteException e) {
3982 * Starts the "new version setup screen" if appropriate.
3984 void startSetupActivityLocked() {
3985 // Only do this once per boot.
3986 if (mCheckedForSetup) {
3990 // We will show this screen if the current one is a different
3991 // version than the last one shown, and we are not running in
3992 // low-level factory test mode.
3993 final ContentResolver resolver = mContext.getContentResolver();
3994 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3995 Settings.Global.getInt(resolver,
3996 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3997 mCheckedForSetup = true;
3999 // See if we should be showing the platform update setup UI.
4000 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4001 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4002 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4003 if (!ris.isEmpty()) {
4004 final ResolveInfo ri = ris.get(0);
4005 String vers = ri.activityInfo.metaData != null
4006 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4008 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4009 vers = ri.activityInfo.applicationInfo.metaData.getString(
4010 Intent.METADATA_SETUP_VERSION);
4012 String lastVers = Settings.Secure.getString(
4013 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4014 if (vers != null && !vers.equals(lastVers)) {
4015 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4016 intent.setComponent(new ComponentName(
4017 ri.activityInfo.packageName, ri.activityInfo.name));
4018 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4019 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4020 null, 0, 0, 0, null, false, false, null, null, null);
4026 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4027 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4030 void enforceNotIsolatedCaller(String caller) {
4031 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4032 throw new SecurityException("Isolated process not allowed to call " + caller);
4036 void enforceShellRestriction(String restriction, int userHandle) {
4037 if (Binder.getCallingUid() == Process.SHELL_UID) {
4038 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4039 throw new SecurityException("Shell does not have permission to access user "
4046 public int getFrontActivityScreenCompatMode() {
4047 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4048 synchronized (this) {
4049 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4054 public void setFrontActivityScreenCompatMode(int mode) {
4055 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4056 "setFrontActivityScreenCompatMode");
4057 synchronized (this) {
4058 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4063 public int getPackageScreenCompatMode(String packageName) {
4064 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4065 synchronized (this) {
4066 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4071 public void setPackageScreenCompatMode(String packageName, int mode) {
4072 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4073 "setPackageScreenCompatMode");
4074 synchronized (this) {
4075 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4080 public boolean getPackageAskScreenCompat(String packageName) {
4081 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4082 synchronized (this) {
4083 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4088 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4089 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4090 "setPackageAskScreenCompat");
4091 synchronized (this) {
4092 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4096 private boolean hasUsageStatsPermission(String callingPackage) {
4097 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4098 Binder.getCallingUid(), callingPackage);
4099 if (mode == AppOpsManager.MODE_DEFAULT) {
4100 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4101 == PackageManager.PERMISSION_GRANTED;
4103 return mode == AppOpsManager.MODE_ALLOWED;
4107 public int getPackageProcessState(String packageName, String callingPackage) {
4108 if (!hasUsageStatsPermission(callingPackage)) {
4109 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4110 "getPackageProcessState");
4113 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4114 synchronized (this) {
4115 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4116 final ProcessRecord proc = mLruProcesses.get(i);
4117 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4118 || procState > proc.setProcState) {
4119 boolean found = false;
4120 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4121 if (proc.pkgList.keyAt(j).equals(packageName)) {
4122 procState = proc.setProcState;
4126 if (proc.pkgDeps != null && !found) {
4127 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4128 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4129 procState = proc.setProcState;
4141 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4142 synchronized (this) {
4143 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4147 if (app.trimMemoryLevel < level && app.thread != null &&
4148 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4149 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4151 app.thread.scheduleTrimMemory(level);
4152 app.trimMemoryLevel = level;
4154 } catch (RemoteException e) {
4155 // Fallthrough to failure case.
4162 private void dispatchProcessesChanged() {
4164 synchronized (this) {
4165 N = mPendingProcessChanges.size();
4166 if (mActiveProcessChanges.length < N) {
4167 mActiveProcessChanges = new ProcessChangeItem[N];
4169 mPendingProcessChanges.toArray(mActiveProcessChanges);
4170 mPendingProcessChanges.clear();
4171 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4172 "*** Delivering " + N + " process changes");
4175 int i = mProcessObservers.beginBroadcast();
4178 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4179 if (observer != null) {
4181 for (int j=0; j<N; j++) {
4182 ProcessChangeItem item = mActiveProcessChanges[j];
4183 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4184 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4185 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4186 + item.uid + ": " + item.foregroundActivities);
4187 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4188 item.foregroundActivities);
4190 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4191 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4192 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4193 + ": " + item.processState);
4194 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4197 } catch (RemoteException e) {
4201 mProcessObservers.finishBroadcast();
4203 synchronized (this) {
4204 for (int j=0; j<N; j++) {
4205 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4210 private void dispatchProcessDied(int pid, int uid) {
4211 int i = mProcessObservers.beginBroadcast();
4214 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4215 if (observer != null) {
4217 observer.onProcessDied(pid, uid);
4218 } catch (RemoteException e) {
4222 mProcessObservers.finishBroadcast();
4225 private void dispatchUidsChanged() {
4227 synchronized (this) {
4228 N = mPendingUidChanges.size();
4229 if (mActiveUidChanges.length < N) {
4230 mActiveUidChanges = new UidRecord.ChangeItem[N];
4232 for (int i=0; i<N; i++) {
4233 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4234 mActiveUidChanges[i] = change;
4235 if (change.uidRecord != null) {
4236 change.uidRecord.pendingChange = null;
4237 change.uidRecord = null;
4240 mPendingUidChanges.clear();
4241 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4242 "*** Delivering " + N + " uid changes");
4245 if (mLocalPowerManager != null) {
4246 for (int j=0; j<N; j++) {
4247 UidRecord.ChangeItem item = mActiveUidChanges[j];
4248 if (item.change == UidRecord.CHANGE_GONE
4249 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4250 mLocalPowerManager.uidGone(item.uid);
4252 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4257 int i = mUidObservers.beginBroadcast();
4260 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4261 final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4262 if (observer != null) {
4264 for (int j=0; j<N; j++) {
4265 UidRecord.ChangeItem item = mActiveUidChanges[j];
4266 final int change = item.change;
4267 UidRecord validateUid = null;
4268 if (VALIDATE_UID_STATES && i == 0) {
4269 validateUid = mValidateUids.get(item.uid);
4270 if (validateUid == null && change != UidRecord.CHANGE_GONE
4271 && change != UidRecord.CHANGE_GONE_IDLE) {
4272 validateUid = new UidRecord(item.uid);
4273 mValidateUids.put(item.uid, validateUid);
4276 if (change == UidRecord.CHANGE_IDLE
4277 || change == UidRecord.CHANGE_GONE_IDLE) {
4278 if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4279 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4280 "UID idle uid=" + item.uid);
4281 observer.onUidIdle(item.uid);
4283 if (VALIDATE_UID_STATES && i == 0) {
4284 if (validateUid != null) {
4285 validateUid.idle = true;
4288 } else if (change == UidRecord.CHANGE_ACTIVE) {
4289 if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4290 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4291 "UID active uid=" + item.uid);
4292 observer.onUidActive(item.uid);
4294 if (VALIDATE_UID_STATES && i == 0) {
4295 validateUid.idle = false;
4298 if (change == UidRecord.CHANGE_GONE
4299 || change == UidRecord.CHANGE_GONE_IDLE) {
4300 if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4301 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4302 "UID gone uid=" + item.uid);
4303 observer.onUidGone(item.uid);
4305 if (VALIDATE_UID_STATES && i == 0) {
4306 if (validateUid != null) {
4307 mValidateUids.remove(item.uid);
4311 if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4312 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4313 "UID CHANGED uid=" + item.uid
4314 + ": " + item.processState);
4315 observer.onUidStateChanged(item.uid, item.processState);
4317 if (VALIDATE_UID_STATES && i == 0) {
4318 validateUid.curProcState = validateUid.setProcState
4319 = item.processState;
4323 } catch (RemoteException e) {
4327 mUidObservers.finishBroadcast();
4329 synchronized (this) {
4330 for (int j=0; j<N; j++) {
4331 mAvailUidChanges.add(mActiveUidChanges[j]);
4337 public final int startActivity(IApplicationThread caller, String callingPackage,
4338 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4339 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4340 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4341 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4342 UserHandle.getCallingUserId());
4345 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4346 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4347 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4348 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4349 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4351 // TODO: Switch to user app stacks here.
4352 String mimeType = intent.getType();
4353 final Uri data = intent.getData();
4354 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4355 mimeType = getProviderMimeType(data, userId);
4357 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4359 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4360 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4361 null, 0, 0, null, null, null, null, false, userId, container, null);
4365 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4366 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4367 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4368 enforceNotIsolatedCaller("startActivity");
4369 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4370 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4371 // TODO: Switch to user app stacks here.
4372 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4373 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4374 profilerInfo, null, null, bOptions, false, userId, null, null);
4378 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4379 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4380 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4383 // This is very dangerous -- it allows you to perform a start activity (including
4384 // permission grants) as any app that may launch one of your own activities. So
4385 // we will only allow this to be done from activities that are part of the core framework,
4386 // and then only when they are running as the system.
4387 final ActivityRecord sourceRecord;
4388 final int targetUid;
4389 final String targetPackage;
4390 synchronized (this) {
4391 if (resultTo == null) {
4392 throw new SecurityException("Must be called from an activity");
4394 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4395 if (sourceRecord == null) {
4396 throw new SecurityException("Called with bad activity token: " + resultTo);
4398 if (!sourceRecord.info.packageName.equals("android")) {
4399 throw new SecurityException(
4400 "Must be called from an activity that is declared in the android package");
4402 if (sourceRecord.app == null) {
4403 throw new SecurityException("Called without a process attached to activity");
4405 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4406 // This is still okay, as long as this activity is running under the
4407 // uid of the original calling activity.
4408 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4409 throw new SecurityException(
4410 "Calling activity in uid " + sourceRecord.app.uid
4411 + " must be system uid or original calling uid "
4412 + sourceRecord.launchedFromUid);
4415 if (ignoreTargetSecurity) {
4416 if (intent.getComponent() == null) {
4417 throw new SecurityException(
4418 "Component must be specified with ignoreTargetSecurity");
4420 if (intent.getSelector() != null) {
4421 throw new SecurityException(
4422 "Selector not allowed with ignoreTargetSecurity");
4425 targetUid = sourceRecord.launchedFromUid;
4426 targetPackage = sourceRecord.launchedFromPackage;
4429 if (userId == UserHandle.USER_NULL) {
4430 userId = UserHandle.getUserId(sourceRecord.app.uid);
4433 // TODO: Switch to user app stacks here.
4435 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4436 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4437 null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4439 } catch (SecurityException e) {
4440 // XXX need to figure out how to propagate to original app.
4441 // A SecurityException here is generally actually a fault of the original
4442 // calling activity (such as a fairly granting permissions), so propagate it
4445 StringBuilder msg = new StringBuilder();
4446 msg.append("While launching");
4447 msg.append(intent.toString());
4449 msg.append(e.getMessage());
4456 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4457 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4458 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4459 enforceNotIsolatedCaller("startActivityAndWait");
4460 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4461 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4462 WaitResult res = new WaitResult();
4463 // TODO: Switch to user app stacks here.
4464 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4465 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4466 bOptions, false, userId, null, null);
4471 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4472 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4473 int startFlags, Configuration config, Bundle bOptions, int userId) {
4474 enforceNotIsolatedCaller("startActivityWithConfig");
4475 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4476 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4477 // TODO: Switch to user app stacks here.
4478 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4479 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4480 null, null, config, bOptions, false, userId, null, null);
4485 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4486 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4487 int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4488 throws TransactionTooLargeException {
4489 enforceNotIsolatedCaller("startActivityIntentSender");
4490 // Refuse possible leaked file descriptors
4491 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4492 throw new IllegalArgumentException("File descriptors passed in Intent");
4495 IIntentSender sender = intent.getTarget();
4496 if (!(sender instanceof PendingIntentRecord)) {
4497 throw new IllegalArgumentException("Bad PendingIntent object");
4500 PendingIntentRecord pir = (PendingIntentRecord)sender;
4502 synchronized (this) {
4503 // If this is coming from the currently resumed activity, it is
4504 // effectively saying that app switches are allowed at this point.
4505 final ActivityStack stack = getFocusedStack();
4506 if (stack.mResumedActivity != null &&
4507 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4508 mAppSwitchesAllowedTime = 0;
4511 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4512 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4517 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4518 Intent intent, String resolvedType, IVoiceInteractionSession session,
4519 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4520 Bundle bOptions, int userId) {
4521 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4522 != PackageManager.PERMISSION_GRANTED) {
4523 String msg = "Permission Denial: startVoiceActivity() from pid="
4524 + Binder.getCallingPid()
4525 + ", uid=" + Binder.getCallingUid()
4526 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4528 throw new SecurityException(msg);
4530 if (session == null || interactor == null) {
4531 throw new NullPointerException("null session or interactor");
4533 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4534 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4535 // TODO: Switch to user app stacks here.
4536 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4537 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4538 null, bOptions, false, userId, null, null);
4542 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4543 throws RemoteException {
4544 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4545 synchronized (this) {
4546 ActivityRecord activity = getFocusedStack().topActivity();
4547 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4548 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4550 if (mRunningVoice != null || activity.task.voiceSession != null
4551 || activity.voiceSession != null) {
4552 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4555 if (activity.pendingVoiceInteractionStart) {
4556 Slog.w(TAG, "Pending start of voice interaction already.");
4559 activity.pendingVoiceInteractionStart = true;
4561 LocalServices.getService(VoiceInteractionManagerInternal.class)
4562 .startLocalVoiceInteraction(callingActivity, options);
4566 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4567 LocalServices.getService(VoiceInteractionManagerInternal.class)
4568 .stopLocalVoiceInteraction(callingActivity);
4572 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4573 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4574 .supportsLocalVoiceInteraction();
4577 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4578 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4579 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4580 if (activityToCallback == null) return;
4581 activityToCallback.setVoiceSessionLocked(voiceSession);
4583 // Inform the activity
4585 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4587 long token = Binder.clearCallingIdentity();
4589 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4591 Binder.restoreCallingIdentity(token);
4593 // TODO: VI Should we cache the activity so that it's easier to find later
4594 // rather than scan through all the stacks and activities?
4595 } catch (RemoteException re) {
4596 activityToCallback.clearVoiceSessionLocked();
4597 // TODO: VI Should this terminate the voice session?
4602 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4603 synchronized (this) {
4604 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4606 mVoiceWakeLock.acquire();
4608 mVoiceWakeLock.release();
4615 public boolean startNextMatchingActivity(IBinder callingActivity,
4616 Intent intent, Bundle bOptions) {
4617 // Refuse possible leaked file descriptors
4618 if (intent != null && intent.hasFileDescriptors() == true) {
4619 throw new IllegalArgumentException("File descriptors passed in Intent");
4621 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4623 synchronized (this) {
4624 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4626 ActivityOptions.abort(options);
4629 if (r.app == null || r.app.thread == null) {
4630 // The caller is not running... d'oh!
4631 ActivityOptions.abort(options);
4634 intent = new Intent(intent);
4635 // The caller is not allowed to change the data.
4636 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4637 // And we are resetting to find the next component...
4638 intent.setComponent(null);
4640 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4642 ActivityInfo aInfo = null;
4644 List<ResolveInfo> resolves =
4645 AppGlobals.getPackageManager().queryIntentActivities(
4646 intent, r.resolvedType,
4647 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4648 UserHandle.getCallingUserId()).getList();
4650 // Look for the original activity in the list...
4651 final int N = resolves != null ? resolves.size() : 0;
4652 for (int i=0; i<N; i++) {
4653 ResolveInfo rInfo = resolves.get(i);
4654 if (rInfo.activityInfo.packageName.equals(r.packageName)
4655 && rInfo.activityInfo.name.equals(r.info.name)) {
4656 // We found the current one... the next matching is
4660 aInfo = resolves.get(i).activityInfo;
4663 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4664 + "/" + r.info.name);
4665 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4666 ? "null" : aInfo.packageName + "/" + aInfo.name));
4671 } catch (RemoteException e) {
4674 if (aInfo == null) {
4675 // Nobody who is next!
4676 ActivityOptions.abort(options);
4677 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4681 intent.setComponent(new ComponentName(
4682 aInfo.applicationInfo.packageName, aInfo.name));
4683 intent.setFlags(intent.getFlags()&~(
4684 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4685 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4686 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4687 Intent.FLAG_ACTIVITY_NEW_TASK));
4689 // Okay now we need to start the new activity, replacing the
4690 // currently running activity. This is a little tricky because
4691 // we want to start the new one as if the current one is finished,
4692 // but not finish the current one first so that there is no flicker.
4694 final boolean wasFinishing = r.finishing;
4697 // Propagate reply information over to the new activity.
4698 final ActivityRecord resultTo = r.resultTo;
4699 final String resultWho = r.resultWho;
4700 final int requestCode = r.requestCode;
4702 if (resultTo != null) {
4703 resultTo.removeResultsLocked(r, resultWho, requestCode);
4706 final long origId = Binder.clearCallingIdentity();
4707 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4708 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4709 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4710 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4711 false, false, null, null, null);
4712 Binder.restoreCallingIdentity(origId);
4714 r.finishing = wasFinishing;
4715 if (res != ActivityManager.START_SUCCESS) {
4723 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4724 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4725 String msg = "Permission Denial: startActivityFromRecents called without " +
4726 START_TASKS_FROM_RECENTS;
4728 throw new SecurityException(msg);
4730 final long origId = Binder.clearCallingIdentity();
4732 synchronized (this) {
4733 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4736 Binder.restoreCallingIdentity(origId);
4740 final int startActivityInPackage(int uid, String callingPackage,
4741 Intent intent, String resolvedType, IBinder resultTo,
4742 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4743 IActivityContainer container, TaskRecord inTask) {
4745 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4746 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4748 // TODO: Switch to user app stacks here.
4749 int ret = mActivityStarter.startActivityMayWait(null, uid, ActivityStarter.PID_NULL, uid,
4750 callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode,
4751 startFlags, null, null, null, bOptions, false, userId, container, inTask);
4756 public final int startActivities(IApplicationThread caller, String callingPackage,
4757 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4759 enforceNotIsolatedCaller("startActivities");
4760 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4761 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4762 // TODO: Switch to user app stacks here.
4763 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4764 resolvedTypes, resultTo, bOptions, userId);
4768 final int startActivitiesInPackage(int uid, String callingPackage,
4769 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4770 Bundle bOptions, int userId) {
4771 return startActivitiesInPackage(uid, ActivityStarter.PID_NULL, UserHandle.USER_NULL,
4772 callingPackage, intents, resolvedTypes, resultTo, bOptions, userId);
4775 final int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid,
4776 String callingPackage, Intent[] intents, String[] resolvedTypes,
4777 IBinder resultTo, Bundle bOptions, int userId) {
4779 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4780 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4781 // TODO: Switch to user app stacks here.
4782 int ret = mActivityStarter.startActivities(null, uid, realCallingPid, realCallingUid,
4783 callingPackage, intents, resolvedTypes, resultTo, bOptions, userId);
4788 public void reportActivityFullyDrawn(IBinder token) {
4789 synchronized (this) {
4790 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4794 r.reportFullyDrawnLocked();
4799 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4800 synchronized (this) {
4801 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4805 TaskRecord task = r.task;
4806 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4807 // Fixed screen orientation isn't supported when activities aren't in full screen
4811 final long origId = Binder.clearCallingIdentity();
4812 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4813 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4814 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4815 if (config != null) {
4816 r.frozenBeforeDestroy = true;
4817 if (!updateConfigurationLocked(config, r, false)) {
4818 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4821 Binder.restoreCallingIdentity(origId);
4826 public int getRequestedOrientation(IBinder token) {
4827 synchronized (this) {
4828 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4830 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4832 return mWindowManager.getAppOrientation(r.appToken);
4837 * This is the internal entry point for handling Activity.finish().
4839 * @param token The Binder token referencing the Activity we want to finish.
4840 * @param resultCode Result code, if any, from this Activity.
4841 * @param resultData Result data (Intent), if any, from this Activity.
4842 * @param finishTask Whether to finish the task associated with this Activity.
4844 * @return Returns true if the activity successfully finished, or false if it is still running.
4847 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4849 // Refuse possible leaked file descriptors
4850 if (resultData != null && resultData.hasFileDescriptors() == true) {
4851 throw new IllegalArgumentException("File descriptors passed in Intent");
4854 synchronized(this) {
4855 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4859 // Keep track of the root activity of the task before we finish it
4860 TaskRecord tr = r.task;
4861 ActivityRecord rootR = tr.getRootActivity();
4862 if (rootR == null) {
4863 Slog.w(TAG, "Finishing task with all activities already finished");
4865 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4867 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4868 mStackSupervisor.isLastLockedTask(tr)) {
4869 Slog.i(TAG, "Not finishing task in lock task mode");
4870 mStackSupervisor.showLockTaskToast();
4873 if (mController != null) {
4874 // Find the first activity that is not finishing.
4875 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4877 // ask watcher if this is allowed
4878 boolean resumeOK = true;
4880 resumeOK = mController.activityResuming(next.packageName);
4881 } catch (RemoteException e) {
4883 Watchdog.getInstance().setActivityController(null);
4887 Slog.i(TAG, "Not finishing activity because controller resumed");
4892 final long origId = Binder.clearCallingIdentity();
4895 final boolean finishWithRootActivity =
4896 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4897 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4898 || (finishWithRootActivity && r == rootR)) {
4899 // If requested, remove the task that is associated to this activity only if it
4900 // was the root activity in the task. The result code and data is ignored
4901 // because we don't support returning them across task boundaries. Also, to
4902 // keep backwards compatibility we remove the task from recents when finishing
4903 // task with root activity.
4904 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4906 Slog.i(TAG, "Removing task failed to finish activity");
4909 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4910 resultData, "app-request", true);
4912 Slog.i(TAG, "Failed to finish by app-request");
4917 Binder.restoreCallingIdentity(origId);
4923 public final void finishHeavyWeightApp() {
4924 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4925 != PackageManager.PERMISSION_GRANTED) {
4926 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4927 + Binder.getCallingPid()
4928 + ", uid=" + Binder.getCallingUid()
4929 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4931 throw new SecurityException(msg);
4934 synchronized(this) {
4935 if (mHeavyWeightProcess == null) {
4939 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4940 for (int i = 0; i < activities.size(); i++) {
4941 ActivityRecord r = activities.get(i);
4942 if (!r.finishing && r.isInStackLocked()) {
4943 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4944 null, "finish-heavy", true);
4948 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4949 mHeavyWeightProcess.userId, 0));
4950 mHeavyWeightProcess = null;
4955 public void crashApplication(int uid, int initialPid, String packageName,
4957 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4958 != PackageManager.PERMISSION_GRANTED) {
4959 String msg = "Permission Denial: crashApplication() from pid="
4960 + Binder.getCallingPid()
4961 + ", uid=" + Binder.getCallingUid()
4962 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4964 throw new SecurityException(msg);
4967 synchronized(this) {
4968 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4973 public final void finishSubActivity(IBinder token, String resultWho,
4975 synchronized(this) {
4976 final long origId = Binder.clearCallingIdentity();
4977 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4979 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4981 Binder.restoreCallingIdentity(origId);
4986 public boolean finishActivityAffinity(IBinder token) {
4987 synchronized(this) {
4988 final long origId = Binder.clearCallingIdentity();
4990 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4995 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4997 final TaskRecord task = r.task;
4998 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4999 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5000 mStackSupervisor.showLockTaskToast();
5003 return task.stack.finishActivityAffinityLocked(r);
5005 Binder.restoreCallingIdentity(origId);
5011 public void finishVoiceTask(IVoiceInteractionSession session) {
5012 synchronized (this) {
5013 final long origId = Binder.clearCallingIdentity();
5015 // TODO: VI Consider treating local voice interactions and voice tasks
5017 mStackSupervisor.finishVoiceTask(session);
5019 Binder.restoreCallingIdentity(origId);
5026 public boolean releaseActivityInstance(IBinder token) {
5027 synchronized(this) {
5028 final long origId = Binder.clearCallingIdentity();
5030 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5034 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5036 Binder.restoreCallingIdentity(origId);
5042 public void releaseSomeActivities(IApplicationThread appInt) {
5043 synchronized(this) {
5044 final long origId = Binder.clearCallingIdentity();
5046 ProcessRecord app = getRecordForAppLocked(appInt);
5047 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5049 Binder.restoreCallingIdentity(origId);
5055 public boolean willActivityBeVisible(IBinder token) {
5056 synchronized(this) {
5057 ActivityStack stack = ActivityRecord.getStackLocked(token);
5058 if (stack != null) {
5059 return stack.willActivityBeVisibleLocked(token);
5066 public void overridePendingTransition(IBinder token, String packageName,
5067 int enterAnim, int exitAnim) {
5068 synchronized(this) {
5069 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5074 final long origId = Binder.clearCallingIdentity();
5076 if (self.state == ActivityState.RESUMED
5077 || self.state == ActivityState.PAUSING) {
5078 mWindowManager.overridePendingAppTransition(packageName,
5079 enterAnim, exitAnim, null);
5082 Binder.restoreCallingIdentity(origId);
5087 * Main function for removing an existing process from the activity manager
5088 * as a result of that process going away. Clears out all connections
5091 private final void handleAppDiedLocked(ProcessRecord app,
5092 boolean restarting, boolean allowRestart) {
5094 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5095 false /*replacingPid*/);
5096 if (!kept && !restarting) {
5097 removeLruProcessLocked(app);
5099 ProcessList.remove(pid);
5103 if (mProfileProc == app) {
5104 clearProfilerLocked();
5107 // Remove this application's activities from active lists.
5108 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5110 app.activities.clear();
5112 if (app.instrumentationClass != null) {
5113 Slog.w(TAG, "Crash of app " + app.processName
5114 + " running instrumentation " + app.instrumentationClass);
5115 Bundle info = new Bundle();
5116 info.putString("shortMsg", "Process crashed.");
5117 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5120 if (!restarting && hasVisibleActivities
5121 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5122 // If there was nothing to resume, and we are not already restarting this process, but
5123 // there is a visible activity that is hosted by the process... then make sure all
5124 // visible activities are running, taking care of restarting this process.
5125 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5129 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5130 IBinder threadBinder = thread.asBinder();
5131 // Find the application record.
5132 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5133 ProcessRecord rec = mLruProcesses.get(i);
5134 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5141 final ProcessRecord getRecordForAppLocked(
5142 IApplicationThread thread) {
5143 if (thread == null) {
5147 int appIndex = getLRURecordIndexForAppLocked(thread);
5148 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5151 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5152 // If there are no longer any background processes running,
5153 // and the app that died was not running instrumentation,
5154 // then tell everyone we are now low on memory.
5155 boolean haveBg = false;
5156 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5157 ProcessRecord rec = mLruProcesses.get(i);
5158 if (rec.thread != null
5159 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5166 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5168 long now = SystemClock.uptimeMillis();
5169 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5172 mLastMemUsageReportTime = now;
5175 final ArrayList<ProcessMemInfo> memInfos
5176 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5177 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5178 long now = SystemClock.uptimeMillis();
5179 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5180 ProcessRecord rec = mLruProcesses.get(i);
5181 if (rec == dyingProc || rec.thread == null) {
5185 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5186 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5188 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5189 // The low memory report is overriding any current
5190 // state for a GC request. Make sure to do
5191 // heavy/important/visible/foreground processes first.
5192 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5193 rec.lastRequestedGc = 0;
5195 rec.lastRequestedGc = rec.lastLowMemory;
5197 rec.reportLowMemory = true;
5198 rec.lastLowMemory = now;
5199 mProcessesToGc.remove(rec);
5200 addProcessToGcListLocked(rec);
5204 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5205 mHandler.sendMessage(msg);
5207 scheduleAppGcsLocked();
5211 final void appDiedLocked(ProcessRecord app) {
5212 appDiedLocked(app, app.pid, app.thread, false);
5215 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5216 boolean fromBinderDied) {
5217 // First check if this ProcessRecord is actually active for the pid.
5218 synchronized (mPidsSelfLocked) {
5219 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5220 if (curProc != app) {
5221 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5226 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5227 synchronized (stats) {
5228 stats.noteProcessDiedLocked(app.info.uid, pid);
5232 if (!fromBinderDied) {
5233 Process.killProcessQuiet(pid);
5235 killProcessGroup(app.uid, pid);
5239 // Clean up already done if the process has been re-started.
5240 if (app.pid == pid && app.thread != null &&
5241 app.thread.asBinder() == thread.asBinder()) {
5242 boolean doLowMem = app.instrumentationClass == null;
5243 boolean doOomAdj = doLowMem;
5244 if (!app.killedByAm) {
5245 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5247 mAllowLowerMemLevel = true;
5249 // Note that we always want to do oom adj to update our state with the
5250 // new number of procs.
5251 mAllowLowerMemLevel = false;
5254 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5255 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5256 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5257 handleAppDiedLocked(app, false, true);
5260 updateOomAdjLocked();
5263 doLowMemReportIfNeededLocked(app);
5265 } else if (app.pid != pid) {
5266 // A new process has already been started.
5267 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5268 + ") has died and restarted (pid " + app.pid + ").");
5269 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5270 } else if (DEBUG_PROCESSES) {
5271 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5272 + thread.asBinder());
5277 * If a stack trace dump file is configured, dump process stack traces.
5278 * @param clearTraces causes the dump file to be erased prior to the new
5279 * traces being written, if true; when false, the new traces will be
5280 * appended to any existing file content.
5281 * @param firstPids of dalvik VM processes to dump stack traces for first
5282 * @param lastPids of dalvik VM processes to dump stack traces for last
5283 * @param nativeProcs optional list of native process names to dump stack crawls
5284 * @return file containing stack traces, or null if no dump file is configured
5286 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5287 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5288 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5289 if (tracesPath == null || tracesPath.length() == 0) {
5293 File tracesFile = new File(tracesPath);
5295 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5296 tracesFile.createNewFile();
5297 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5298 } catch (IOException e) {
5299 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5303 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5307 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5308 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5309 // Use a FileObserver to detect when traces finish writing.
5310 // The order of traces is considered important to maintain for legibility.
5311 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5313 public synchronized void onEvent(int event, String path) { notify(); }
5317 observer.startWatching();
5319 // First collect all of the stacks of the most important pids.
5320 if (firstPids != null) {
5322 int num = firstPids.size();
5323 for (int i = 0; i < num; i++) {
5324 synchronized (observer) {
5325 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5326 + firstPids.get(i));
5327 final long sime = SystemClock.elapsedRealtime();
5328 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5329 observer.wait(1000); // Wait for write-close, give up after 1 sec
5330 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5331 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5334 } catch (InterruptedException e) {
5339 // Next collect the stacks of the native pids
5340 if (nativeProcs != null) {
5341 int[] pids = Process.getPidsForCommands(nativeProcs);
5343 for (int pid : pids) {
5344 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5345 final long sime = SystemClock.elapsedRealtime();
5346 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5347 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5348 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5353 // Lastly, measure CPU usage.
5354 if (processCpuTracker != null) {
5355 processCpuTracker.init();
5357 processCpuTracker.update();
5359 synchronized (processCpuTracker) {
5360 processCpuTracker.wait(500); // measure over 1/2 second.
5362 } catch (InterruptedException e) {
5364 processCpuTracker.update();
5366 // We'll take the stack crawls of just the top apps using CPU.
5367 final int N = processCpuTracker.countWorkingStats();
5369 for (int i=0; i<N && numProcs<5; i++) {
5370 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5371 if (lastPids.indexOfKey(stats.pid) >= 0) {
5374 synchronized (observer) {
5375 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5377 final long stime = SystemClock.elapsedRealtime();
5378 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5379 observer.wait(1000); // Wait for write-close, give up after 1 sec
5380 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5381 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5383 } catch (InterruptedException e) {
5386 } else if (DEBUG_ANR) {
5387 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5393 observer.stopWatching();
5397 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5398 if (true || IS_USER_BUILD) {
5401 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5402 if (tracesPath == null || tracesPath.length() == 0) {
5406 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5407 StrictMode.allowThreadDiskWrites();
5409 final File tracesFile = new File(tracesPath);
5410 final File tracesDir = tracesFile.getParentFile();
5411 final File tracesTmp = new File(tracesDir, "__tmp__");
5413 if (tracesFile.exists()) {
5415 tracesFile.renameTo(tracesTmp);
5417 StringBuilder sb = new StringBuilder();
5418 Time tobj = new Time();
5419 tobj.set(System.currentTimeMillis());
5420 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5422 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5423 sb.append(" since ");
5425 FileOutputStream fos = new FileOutputStream(tracesFile);
5426 fos.write(sb.toString().getBytes());
5428 fos.write("\n*** No application process!".getBytes());
5431 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5432 } catch (IOException e) {
5433 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5438 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5439 firstPids.add(app.pid);
5440 dumpStackTraces(tracesPath, firstPids, null, null, null);
5443 File lastTracesFile = null;
5444 File curTracesFile = null;
5445 for (int i=9; i>=0; i--) {
5446 String name = String.format(Locale.US, "slow%02d.txt", i);
5447 curTracesFile = new File(tracesDir, name);
5448 if (curTracesFile.exists()) {
5449 if (lastTracesFile != null) {
5450 curTracesFile.renameTo(lastTracesFile);
5452 curTracesFile.delete();
5455 lastTracesFile = curTracesFile;
5457 tracesFile.renameTo(curTracesFile);
5458 if (tracesTmp.exists()) {
5459 tracesTmp.renameTo(tracesFile);
5462 StrictMode.setThreadPolicy(oldPolicy);
5466 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5467 if (!mLaunchWarningShown) {
5468 mLaunchWarningShown = true;
5469 mUiHandler.post(new Runnable() {
5472 synchronized (ActivityManagerService.this) {
5473 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5475 mUiHandler.postDelayed(new Runnable() {
5478 synchronized (ActivityManagerService.this) {
5480 mLaunchWarningShown = false;
5491 public boolean clearApplicationUserData(final String packageName,
5492 final IPackageDataObserver observer, int userId) {
5493 enforceNotIsolatedCaller("clearApplicationUserData");
5494 int uid = Binder.getCallingUid();
5495 int pid = Binder.getCallingPid();
5496 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5497 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5500 long callingId = Binder.clearCallingIdentity();
5502 IPackageManager pm = AppGlobals.getPackageManager();
5504 synchronized(this) {
5505 if (getPackageManagerInternalLocked().isPackageDataProtected(
5506 userId, packageName)) {
5507 throw new SecurityException(
5508 "Cannot clear data for a protected package: " + packageName);
5512 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5513 } catch (RemoteException e) {
5516 Slog.w(TAG, "Invalid packageName: " + packageName);
5517 if (observer != null) {
5519 observer.onRemoveCompleted(packageName, false);
5520 } catch (RemoteException e) {
5521 Slog.i(TAG, "Observer no longer exists.");
5526 if (uid == pkgUid || checkComponentPermission(
5527 android.Manifest.permission.CLEAR_APP_USER_DATA,
5529 == PackageManager.PERMISSION_GRANTED) {
5530 forceStopPackageLocked(packageName, pkgUid, "clear data");
5532 throw new SecurityException("PID " + pid + " does not have permission "
5533 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5534 + " of package " + packageName);
5537 // Remove all tasks match the cleared application package and user
5538 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5539 final TaskRecord tr = mRecentTasks.get(i);
5540 final String taskPackageName =
5541 tr.getBaseIntent().getComponent().getPackageName();
5542 if (tr.userId != userId) continue;
5543 if (!taskPackageName.equals(packageName)) continue;
5544 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5548 final int pkgUidF = pkgUid;
5549 final int userIdF = userId;
5550 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5552 public void onRemoveCompleted(String packageName, boolean succeeded)
5553 throws RemoteException {
5554 synchronized (ActivityManagerService.this) {
5555 finishForceStopPackageLocked(packageName, pkgUidF);
5558 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5559 Uri.fromParts("package", packageName, null));
5560 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5561 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5562 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5563 null, null, 0, null, null, null, null, false, false, userIdF);
5565 if (observer != null) {
5566 observer.onRemoveCompleted(packageName, succeeded);
5572 // Clear application user data
5573 pm.clearApplicationUserData(packageName, localObserver, userId);
5575 synchronized(this) {
5576 // Remove all permissions granted from/to this package
5577 removeUriPermissionsForPackageLocked(packageName, userId, true);
5580 // Remove all zen rules created by this package; revoke it's zen access.
5581 INotificationManager inm = NotificationManager.getService();
5582 inm.removeAutomaticZenRules(packageName);
5583 inm.setNotificationPolicyAccessGranted(packageName, false);
5585 } catch (RemoteException e) {
5588 Binder.restoreCallingIdentity(callingId);
5594 public void killBackgroundProcesses(final String packageName, int userId) {
5595 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5596 != PackageManager.PERMISSION_GRANTED &&
5597 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5598 != PackageManager.PERMISSION_GRANTED) {
5599 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5600 + Binder.getCallingPid()
5601 + ", uid=" + Binder.getCallingUid()
5602 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5604 throw new SecurityException(msg);
5607 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5608 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5609 long callingId = Binder.clearCallingIdentity();
5611 IPackageManager pm = AppGlobals.getPackageManager();
5612 synchronized(this) {
5615 appId = UserHandle.getAppId(
5616 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5617 } catch (RemoteException e) {
5620 Slog.w(TAG, "Invalid packageName: " + packageName);
5623 killPackageProcessesLocked(packageName, appId, userId,
5624 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5627 Binder.restoreCallingIdentity(callingId);
5632 public void killAllBackgroundProcesses() {
5633 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5634 != PackageManager.PERMISSION_GRANTED) {
5635 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5636 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5637 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5639 throw new SecurityException(msg);
5642 final long callingId = Binder.clearCallingIdentity();
5644 synchronized (this) {
5645 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5646 final int NP = mProcessNames.getMap().size();
5647 for (int ip = 0; ip < NP; ip++) {
5648 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5649 final int NA = apps.size();
5650 for (int ia = 0; ia < NA; ia++) {
5651 final ProcessRecord app = apps.valueAt(ia);
5652 if (app.persistent) {
5653 // We don't kill persistent processes.
5658 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5665 final int N = procs.size();
5666 for (int i = 0; i < N; i++) {
5667 removeProcessLocked(procs.get(i), false, true, "kill all background");
5670 mAllowLowerMemLevel = true;
5672 updateOomAdjLocked();
5673 doLowMemReportIfNeededLocked(null);
5676 Binder.restoreCallingIdentity(callingId);
5681 * Kills all background processes, except those matching any of the
5682 * specified properties.
5684 * @param minTargetSdk the target SDK version at or above which to preserve
5685 * processes, or {@code -1} to ignore the target SDK
5686 * @param maxProcState the process state at or below which to preserve
5687 * processes, or {@code -1} to ignore the process state
5689 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5690 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5691 != PackageManager.PERMISSION_GRANTED) {
5692 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5693 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5694 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5696 throw new SecurityException(msg);
5699 final long callingId = Binder.clearCallingIdentity();
5701 synchronized (this) {
5702 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5703 final int NP = mProcessNames.getMap().size();
5704 for (int ip = 0; ip < NP; ip++) {
5705 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5706 final int NA = apps.size();
5707 for (int ia = 0; ia < NA; ia++) {
5708 final ProcessRecord app = apps.valueAt(ia);
5711 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5712 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5719 final int N = procs.size();
5720 for (int i = 0; i < N; i++) {
5721 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5725 Binder.restoreCallingIdentity(callingId);
5730 public void forceStopPackage(final String packageName, int userId) {
5731 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5732 != PackageManager.PERMISSION_GRANTED) {
5733 String msg = "Permission Denial: forceStopPackage() from pid="
5734 + Binder.getCallingPid()
5735 + ", uid=" + Binder.getCallingUid()
5736 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5738 throw new SecurityException(msg);
5740 final int callingPid = Binder.getCallingPid();
5741 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5742 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5743 long callingId = Binder.clearCallingIdentity();
5745 IPackageManager pm = AppGlobals.getPackageManager();
5746 synchronized(this) {
5747 int[] users = userId == UserHandle.USER_ALL
5748 ? mUserController.getUsers() : new int[] { userId };
5749 for (int user : users) {
5752 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5754 } catch (RemoteException e) {
5757 Slog.w(TAG, "Invalid packageName: " + packageName);
5761 pm.setPackageStoppedState(packageName, true, user);
5762 } catch (RemoteException e) {
5763 } catch (IllegalArgumentException e) {
5764 Slog.w(TAG, "Failed trying to unstop package "
5765 + packageName + ": " + e);
5767 if (mUserController.isUserRunningLocked(user, 0)) {
5768 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5769 finishForceStopPackageLocked(packageName, pkgUid);
5774 Binder.restoreCallingIdentity(callingId);
5779 public void addPackageDependency(String packageName) {
5780 synchronized (this) {
5781 int callingPid = Binder.getCallingPid();
5782 if (callingPid == Process.myPid()) {
5787 synchronized (mPidsSelfLocked) {
5788 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5791 if (proc.pkgDeps == null) {
5792 proc.pkgDeps = new ArraySet<String>(1);
5794 proc.pkgDeps.add(packageName);
5800 * The pkg name and app id have to be specified.
5803 public void killApplication(String pkg, int appId, int userId, String reason) {
5807 // Make sure the uid is valid.
5809 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5812 int callerUid = Binder.getCallingUid();
5813 // Only the system server can kill an application
5814 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5815 // Post an aysnc message to kill the application
5816 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5819 Bundle bundle = new Bundle();
5820 bundle.putString("pkg", pkg);
5821 bundle.putString("reason", reason);
5823 mHandler.sendMessage(msg);
5825 throw new SecurityException(callerUid + " cannot kill pkg: " +
5831 public void closeSystemDialogs(String reason) {
5832 enforceNotIsolatedCaller("closeSystemDialogs");
5834 final int pid = Binder.getCallingPid();
5835 final int uid = Binder.getCallingUid();
5836 final long origId = Binder.clearCallingIdentity();
5838 synchronized (this) {
5839 // Only allow this from foreground processes, so that background
5840 // applications can't abuse it to prevent system UI from being shown.
5841 if (uid >= Process.FIRST_APPLICATION_UID) {
5843 synchronized (mPidsSelfLocked) {
5844 proc = mPidsSelfLocked.get(pid);
5846 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5847 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5848 + " from background process " + proc);
5852 closeSystemDialogsLocked(reason);
5855 Binder.restoreCallingIdentity(origId);
5859 void closeSystemDialogsLocked(String reason) {
5860 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5861 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5862 | Intent.FLAG_RECEIVER_FOREGROUND);
5863 if (reason != null) {
5864 intent.putExtra("reason", reason);
5866 mWindowManager.closeSystemDialogs(reason);
5868 mStackSupervisor.closeSystemDialogsLocked();
5870 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5871 AppOpsManager.OP_NONE, null, false, false,
5872 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5876 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5877 enforceNotIsolatedCaller("getProcessMemoryInfo");
5878 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5879 for (int i=pids.length-1; i>=0; i--) {
5882 synchronized (this) {
5883 synchronized (mPidsSelfLocked) {
5884 proc = mPidsSelfLocked.get(pids[i]);
5885 oomAdj = proc != null ? proc.setAdj : 0;
5888 infos[i] = new Debug.MemoryInfo();
5889 Debug.getMemoryInfo(pids[i], infos[i]);
5891 synchronized (this) {
5892 if (proc.thread != null && proc.setAdj == oomAdj) {
5893 // Record this for posterity if the process has been stable.
5894 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5895 infos[i].getTotalUss(), false, proc.pkgList);
5904 public long[] getProcessPss(int[] pids) {
5905 enforceNotIsolatedCaller("getProcessPss");
5906 long[] pss = new long[pids.length];
5907 for (int i=pids.length-1; i>=0; i--) {
5910 synchronized (this) {
5911 synchronized (mPidsSelfLocked) {
5912 proc = mPidsSelfLocked.get(pids[i]);
5913 oomAdj = proc != null ? proc.setAdj : 0;
5916 long[] tmpUss = new long[1];
5917 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5919 synchronized (this) {
5920 if (proc.thread != null && proc.setAdj == oomAdj) {
5921 // Record this for posterity if the process has been stable.
5922 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5931 public void killApplicationProcess(String processName, int uid) {
5932 if (processName == null) {
5936 int callerUid = Binder.getCallingUid();
5937 // Only the system server can kill an application
5938 if (callerUid == Process.SYSTEM_UID) {
5939 synchronized (this) {
5940 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5941 if (app != null && app.thread != null) {
5943 app.thread.scheduleSuicide();
5944 } catch (RemoteException e) {
5945 // If the other end already died, then our work here is done.
5948 Slog.w(TAG, "Process/uid not found attempting kill of "
5949 + processName + " / " + uid);
5953 throw new SecurityException(callerUid + " cannot kill app process: " +
5958 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5959 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5960 false, true, false, false, UserHandle.getUserId(uid), reason);
5963 private void finishForceStopPackageLocked(final String packageName, int uid) {
5964 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5965 Uri.fromParts("package", packageName, null));
5966 if (!mProcessesReady) {
5967 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5968 | Intent.FLAG_RECEIVER_FOREGROUND);
5970 intent.putExtra(Intent.EXTRA_UID, uid);
5971 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5972 broadcastIntentLocked(null, null, intent,
5973 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5974 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5978 private final boolean killPackageProcessesLocked(String packageName, int appId,
5979 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5980 boolean doit, boolean evenPersistent, String reason) {
5981 ArrayList<ProcessRecord> procs = new ArrayList<>();
5983 // Remove all processes this package may have touched: all with the
5984 // same UID (except for the system or root user), and all whose name
5985 // matches the package name.
5986 final int NP = mProcessNames.getMap().size();
5987 for (int ip=0; ip<NP; ip++) {
5988 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5989 final int NA = apps.size();
5990 for (int ia=0; ia<NA; ia++) {
5991 ProcessRecord app = apps.valueAt(ia);
5992 if (app.persistent && !evenPersistent) {
5993 // we don't kill persistent processes
6003 // Skip process if it doesn't meet our oom adj requirement.
6004 if (app.setAdj < minOomAdj) {
6008 // If no package is specified, we call all processes under the
6010 if (packageName == null) {
6011 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6014 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6017 // Package has been specified, we want to hit all processes
6018 // that match it. We need to qualify this by the processes
6019 // that are running under the specified app and user ID.
6021 final boolean isDep = app.pkgDeps != null
6022 && app.pkgDeps.contains(packageName);
6023 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6026 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6029 if (!app.pkgList.containsKey(packageName) && !isDep) {
6034 // Process has passed all conditions, kill it!
6043 int N = procs.size();
6044 for (int i=0; i<N; i++) {
6045 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6047 updateOomAdjLocked();
6051 private void cleanupDisabledPackageComponentsLocked(
6052 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6054 Set<String> disabledClasses = null;
6055 boolean packageDisabled = false;
6056 IPackageManager pm = AppGlobals.getPackageManager();
6058 if (changedClasses == null) {
6059 // Nothing changed...
6063 // Determine enable/disable state of the package and its components.
6064 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6065 for (int i = changedClasses.length - 1; i >= 0; i--) {
6066 final String changedClass = changedClasses[i];
6068 if (changedClass.equals(packageName)) {
6070 // Entire package setting changed
6071 enabled = pm.getApplicationEnabledSetting(packageName,
6072 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6073 } catch (Exception e) {
6074 // No such package/component; probably racing with uninstall. In any
6075 // event it means we have nothing further to do here.
6078 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6079 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6080 if (packageDisabled) {
6081 // Entire package is disabled.
6082 // No need to continue to check component states.
6083 disabledClasses = null;
6088 enabled = pm.getComponentEnabledSetting(
6089 new ComponentName(packageName, changedClass),
6090 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6091 } catch (Exception e) {
6092 // As above, probably racing with uninstall.
6095 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6096 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6097 if (disabledClasses == null) {
6098 disabledClasses = new ArraySet<>(changedClasses.length);
6100 disabledClasses.add(changedClass);
6105 if (!packageDisabled && disabledClasses == null) {
6106 // Nothing to do here...
6110 // Clean-up disabled activities.
6111 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6112 packageName, disabledClasses, true, false, userId) && mBooted) {
6113 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6114 mStackSupervisor.scheduleIdleLocked();
6117 // Clean-up disabled tasks
6118 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6120 // Clean-up disabled services.
6121 mServices.bringDownDisabledPackageServicesLocked(
6122 packageName, disabledClasses, userId, false, killProcess, true);
6124 // Clean-up disabled providers.
6125 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6126 mProviderMap.collectPackageProvidersLocked(
6127 packageName, disabledClasses, true, false, userId, providers);
6128 for (int i = providers.size() - 1; i >= 0; i--) {
6129 removeDyingProviderLocked(null, providers.get(i), true);
6132 // Clean-up disabled broadcast receivers.
6133 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6134 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6135 packageName, disabledClasses, userId, true);
6140 final boolean clearBroadcastQueueForUserLocked(int userId) {
6141 boolean didSomething = false;
6142 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6143 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6144 null, null, userId, true);
6146 return didSomething;
6149 final boolean forceStopPackageLocked(String packageName, int appId,
6150 boolean callerWillRestart, boolean purgeCache, boolean doit,
6151 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6154 if (userId == UserHandle.USER_ALL && packageName == null) {
6155 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6158 if (appId < 0 && packageName != null) {
6160 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6161 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6162 } catch (RemoteException e) {
6167 if (packageName != null) {
6168 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6169 + " user=" + userId + ": " + reason);
6171 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6174 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6177 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6178 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6179 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6181 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6182 packageName, null, doit, evenPersistent, userId)) {
6186 didSomething = true;
6189 if (mServices.bringDownDisabledPackageServicesLocked(
6190 packageName, null, userId, evenPersistent, true, doit)) {
6194 didSomething = true;
6197 if (packageName == null) {
6198 // Remove all sticky broadcasts from this user.
6199 mStickyBroadcasts.remove(userId);
6202 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6203 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6204 userId, providers)) {
6208 didSomething = true;
6210 for (i = providers.size() - 1; i >= 0; i--) {
6211 removeDyingProviderLocked(null, providers.get(i), true);
6214 // Remove transient permissions granted from/to this package/user
6215 removeUriPermissionsForPackageLocked(packageName, userId, false);
6218 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6219 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6220 packageName, null, userId, doit);
6224 if (packageName == null || uninstalling) {
6225 // Remove pending intents. For now we only do this when force
6226 // stopping users, because we have some problems when doing this
6227 // for packages -- app widgets are not currently cleaned up for
6228 // such packages, so they can be left with bad pending intents.
6229 if (mIntentSenderRecords.size() > 0) {
6230 Iterator<WeakReference<PendingIntentRecord>> it
6231 = mIntentSenderRecords.values().iterator();
6232 while (it.hasNext()) {
6233 WeakReference<PendingIntentRecord> wpir = it.next();
6238 PendingIntentRecord pir = wpir.get();
6243 if (packageName == null) {
6244 // Stopping user, remove all objects for the user.
6245 if (pir.key.userId != userId) {
6246 // Not the same user, skip it.
6250 if (UserHandle.getAppId(pir.uid) != appId) {
6251 // Different app id, skip it.
6254 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6255 // Different user, skip it.
6258 if (!pir.key.packageName.equals(packageName)) {
6259 // Different package, skip it.
6266 didSomething = true;
6268 pir.canceled = true;
6269 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6270 pir.key.activity.pendingResults.remove(pir.ref);
6277 if (purgeCache && packageName != null) {
6278 AttributeCache ac = AttributeCache.instance();
6280 ac.removePackage(packageName);
6284 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6285 mStackSupervisor.scheduleIdleLocked();
6289 return didSomething;
6292 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6293 return removeProcessNameLocked(name, uid, null);
6296 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6297 final ProcessRecord expecting) {
6298 ProcessRecord old = mProcessNames.get(name, uid);
6299 // Only actually remove when the currently recorded value matches the
6300 // record that we expected; if it doesn't match then we raced with a
6301 // newly created process and we don't want to destroy the new one.
6302 if ((expecting == null) || (old == expecting)) {
6303 mProcessNames.remove(name, uid);
6305 if (old != null && old.uidRecord != null) {
6306 old.uidRecord.numProcs--;
6307 if (old.uidRecord.numProcs == 0) {
6308 // No more processes using this uid, tell clients it is gone.
6309 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6310 "No more processes in " + old.uidRecord);
6311 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6312 mActiveUids.remove(uid);
6313 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6315 old.uidRecord = null;
6317 mIsolatedProcesses.remove(uid);
6321 private final void addProcessNameLocked(ProcessRecord proc) {
6322 // We shouldn't already have a process under this name, but just in case we
6323 // need to clean up whatever may be there now.
6324 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6325 if (old == proc && proc.persistent) {
6326 // We are re-adding a persistent process. Whatevs! Just leave it there.
6327 Slog.w(TAG, "Re-adding persistent process " + proc);
6328 } else if (old != null) {
6329 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6331 UidRecord uidRec = mActiveUids.get(proc.uid);
6332 if (uidRec == null) {
6333 uidRec = new UidRecord(proc.uid);
6334 // This is the first appearance of the uid, report it now!
6335 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6336 "Creating new process uid: " + uidRec);
6337 mActiveUids.put(proc.uid, uidRec);
6338 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6339 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6341 proc.uidRecord = uidRec;
6343 // Reset render thread tid if it was already set, so new process can set it again.
6344 proc.renderThreadTid = 0;
6346 mProcessNames.put(proc.processName, proc.uid, proc);
6347 if (proc.isolated) {
6348 mIsolatedProcesses.put(proc.uid, proc);
6352 boolean removeProcessLocked(ProcessRecord app,
6353 boolean callerWillRestart, boolean allowRestart, String reason) {
6354 final String name = app.processName;
6355 final int uid = app.uid;
6356 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6357 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6359 ProcessRecord old = mProcessNames.get(name, uid);
6361 // This process is no longer active, so nothing to do.
6362 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6365 removeProcessNameLocked(name, uid);
6366 if (mHeavyWeightProcess == app) {
6367 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6368 mHeavyWeightProcess.userId, 0));
6369 mHeavyWeightProcess = null;
6371 boolean needRestart = false;
6372 if (app.pid > 0 && app.pid != MY_PID) {
6374 synchronized (mPidsSelfLocked) {
6375 mPidsSelfLocked.remove(pid);
6376 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6378 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6380 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6382 boolean willRestart = false;
6383 if (app.persistent && !app.isolated) {
6384 if (!callerWillRestart) {
6390 app.kill(reason, true);
6391 handleAppDiedLocked(app, willRestart, allowRestart);
6393 removeLruProcessLocked(app);
6394 addAppLocked(app.info, false, null /* ABI override */);
6397 mRemovedProcesses.add(app);
6403 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6404 cleanupAppInLaunchingProvidersLocked(app, true);
6405 removeProcessLocked(app, false, true, "timeout publishing content providers");
6408 private final void processStartTimedOutLocked(ProcessRecord app) {
6409 final int pid = app.pid;
6410 boolean gone = false;
6411 synchronized (mPidsSelfLocked) {
6412 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6413 if (knownApp != null && knownApp.thread == null) {
6414 mPidsSelfLocked.remove(pid);
6420 Slog.w(TAG, "Process " + app + " failed to attach");
6421 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6422 pid, app.uid, app.processName);
6423 removeProcessNameLocked(app.processName, app.uid);
6424 if (mHeavyWeightProcess == app) {
6425 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6426 mHeavyWeightProcess.userId, 0));
6427 mHeavyWeightProcess = null;
6429 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6431 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6433 // Take care of any launching providers waiting for this process.
6434 cleanupAppInLaunchingProvidersLocked(app, true);
6435 // Take care of any services that are waiting for the process.
6436 mServices.processStartTimedOutLocked(app);
6437 app.kill("start timeout", true);
6438 removeLruProcessLocked(app);
6439 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6440 Slog.w(TAG, "Unattached app died before backup, skipping");
6442 IBackupManager bm = IBackupManager.Stub.asInterface(
6443 ServiceManager.getService(Context.BACKUP_SERVICE));
6444 bm.agentDisconnected(app.info.packageName);
6445 } catch (RemoteException e) {
6446 // Can't happen; the backup manager is local
6449 if (isPendingBroadcastProcessLocked(pid)) {
6450 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6451 skipPendingBroadcastLocked(pid);
6454 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6458 private final boolean attachApplicationLocked(IApplicationThread thread,
6461 // Find the application record that is being attached... either via
6462 // the pid if we are running in multiple processes, or just pull the
6463 // next app record if we are emulating process with anonymous threads.
6465 long startTime = SystemClock.uptimeMillis();
6466 if (pid != MY_PID && pid >= 0) {
6467 synchronized (mPidsSelfLocked) {
6468 app = mPidsSelfLocked.get(pid);
6475 Slog.w(TAG, "No pending application record for pid " + pid
6476 + " (IApplicationThread " + thread + "); dropping process");
6477 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6478 if (pid > 0 && pid != MY_PID) {
6479 Process.killProcessQuiet(pid);
6480 //TODO: killProcessGroup(app.info.uid, pid);
6483 thread.scheduleExit();
6484 } catch (Exception e) {
6485 // Ignore exceptions.
6491 // If this application record is still attached to a previous
6492 // process, clean it up now.
6493 if (app.thread != null) {
6494 handleAppDiedLocked(app, true, true);
6497 // Tell the process all about itself.
6499 if (DEBUG_ALL) Slog.v(
6500 TAG, "Binding process pid " + pid + " to record " + app);
6502 final String processName = app.processName;
6504 AppDeathRecipient adr = new AppDeathRecipient(
6506 thread.asBinder().linkToDeath(adr, 0);
6507 app.deathRecipient = adr;
6508 } catch (RemoteException e) {
6509 app.resetPackageList(mProcessStats);
6510 startProcessLocked(app, "link fail", processName);
6514 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6516 app.makeActive(thread, mProcessStats);
6517 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6518 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6519 app.forcingToForeground = null;
6520 updateProcessForegroundLocked(app, false, false);
6521 app.hasShownUi = false;
6522 app.debugging = false;
6524 app.killedByAm = false;
6526 // We carefully use the same state that PackageManager uses for
6527 // filtering, since we use this flag to decide if we need to install
6528 // providers when user is unlocked later
6529 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6531 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6533 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6534 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6536 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6537 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6539 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6542 checkTime(startTime, "attachApplicationLocked: before bindApplication");
6545 Slog.i(TAG, "Launching preboot mode app: " + app);
6548 if (DEBUG_ALL) Slog.v(
6549 TAG, "New app record " + app
6550 + " thread=" + thread.asBinder() + " pid=" + pid);
6552 int testMode = IApplicationThread.DEBUG_OFF;
6553 if (mDebugApp != null && mDebugApp.equals(processName)) {
6554 testMode = mWaitForDebugger
6555 ? IApplicationThread.DEBUG_WAIT
6556 : IApplicationThread.DEBUG_ON;
6557 app.debugging = true;
6558 if (mDebugTransient) {
6559 mDebugApp = mOrigDebugApp;
6560 mWaitForDebugger = mOrigWaitForDebugger;
6563 String profileFile = app.instrumentationProfileFile;
6564 ParcelFileDescriptor profileFd = null;
6565 int samplingInterval = 0;
6566 boolean profileAutoStop = false;
6567 if (mProfileApp != null && mProfileApp.equals(processName)) {
6569 profileFile = mProfileFile;
6570 profileFd = mProfileFd;
6571 samplingInterval = mSamplingInterval;
6572 profileAutoStop = mAutoStopProfiler;
6574 boolean enableTrackAllocation = false;
6575 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6576 enableTrackAllocation = true;
6577 mTrackAllocationApp = null;
6580 // If the app is being launched for restore or full backup, set it up specially
6581 boolean isRestrictedBackupMode = false;
6582 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6583 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6584 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6585 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6586 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6589 if (app.instrumentationClass != null) {
6590 notifyPackageUse(app.instrumentationClass.getPackageName(),
6591 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6593 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6594 + processName + " with config " + mConfiguration);
6595 ApplicationInfo appInfo = app.instrumentationInfo != null
6596 ? app.instrumentationInfo : app.info;
6597 app.compat = compatibilityInfoForPackageLocked(appInfo);
6598 if (profileFd != null) {
6599 profileFd = profileFd.dup();
6601 ProfilerInfo profilerInfo = profileFile == null ? null
6602 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6603 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6604 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6605 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6606 app.instrumentationUiAutomationConnection, testMode,
6607 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6608 isRestrictedBackupMode || !normalMode, app.persistent,
6609 new Configuration(mConfiguration), app.compat,
6610 getCommonServicesLocked(app.isolated),
6611 mCoreSettingsObserver.getCoreSettingsLocked());
6612 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6613 updateLruProcessLocked(app, false, null);
6614 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6615 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6616 } catch (Exception e) {
6617 // todo: Yikes! What should we do? For now we will try to
6618 // start another process, but that could easily get us in
6619 // an infinite loop of restarting processes...
6620 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6622 app.resetPackageList(mProcessStats);
6623 app.unlinkDeathRecipient();
6624 startProcessLocked(app, "bind fail", processName);
6628 // Remove this record from the list of starting applications.
6629 mPersistentStartingProcesses.remove(app);
6630 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6631 "Attach application locked removing on hold: " + app);
6632 mProcessesOnHold.remove(app);
6634 boolean badApp = false;
6635 boolean didSomething = false;
6637 // See if the top visible activity is waiting to run in this process...
6640 if (mStackSupervisor.attachApplicationLocked(app)) {
6641 didSomething = true;
6643 } catch (Exception e) {
6644 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6649 // Find any services that should be running in this process...
6652 didSomething |= mServices.attachApplicationLocked(app, processName);
6653 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6654 } catch (Exception e) {
6655 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6660 // Check if a next-broadcast receiver is in this process...
6661 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6663 didSomething |= sendPendingBroadcastsLocked(app);
6664 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6665 } catch (Exception e) {
6666 // If the app died trying to launch the receiver we declare it 'bad'
6667 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6672 // Check whether the next backup agent is in this process...
6673 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6674 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6675 "New app is backup target, launching agent for " + app);
6676 notifyPackageUse(mBackupTarget.appInfo.packageName,
6677 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6679 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6680 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6681 mBackupTarget.backupMode);
6682 } catch (Exception e) {
6683 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6689 app.kill("error during init", true);
6690 handleAppDiedLocked(app, false, true);
6694 if (!didSomething) {
6695 updateOomAdjLocked();
6696 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6703 public final void attachApplication(IApplicationThread thread) {
6704 synchronized (this) {
6705 int callingPid = Binder.getCallingPid();
6706 final long origId = Binder.clearCallingIdentity();
6707 attachApplicationLocked(thread, callingPid);
6708 Binder.restoreCallingIdentity(origId);
6713 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6714 final long origId = Binder.clearCallingIdentity();
6715 synchronized (this) {
6716 ActivityStack stack = ActivityRecord.getStackLocked(token);
6717 if (stack != null) {
6719 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6720 if (stopProfiling) {
6721 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6724 } catch (IOException e) {
6726 clearProfilerLocked();
6731 Binder.restoreCallingIdentity(origId);
6734 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6735 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6736 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6739 void enableScreenAfterBoot() {
6740 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6741 SystemClock.uptimeMillis());
6742 mWindowManager.enableScreenAfterBoot();
6744 synchronized (this) {
6745 updateEventDispatchingLocked();
6750 public void showBootMessage(final CharSequence msg, final boolean always) {
6751 if (Binder.getCallingUid() != Process.myUid()) {
6752 throw new SecurityException();
6754 mWindowManager.showBootMessage(msg, always);
6758 public void keyguardWaitingForActivityDrawn() {
6759 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6760 final long token = Binder.clearCallingIdentity();
6762 synchronized (this) {
6763 if (DEBUG_LOCKSCREEN) logLockScreen("");
6764 mWindowManager.keyguardWaitingForActivityDrawn();
6765 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6766 mLockScreenShown = LOCK_SCREEN_LEAVING;
6767 updateSleepIfNeededLocked();
6771 Binder.restoreCallingIdentity(token);
6776 public void keyguardGoingAway(int flags) {
6777 enforceNotIsolatedCaller("keyguardGoingAway");
6778 final long token = Binder.clearCallingIdentity();
6780 synchronized (this) {
6781 if (DEBUG_LOCKSCREEN) logLockScreen("");
6782 mWindowManager.keyguardGoingAway(flags);
6783 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6784 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6785 updateSleepIfNeededLocked();
6787 // Some stack visibility might change (e.g. docked stack)
6788 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6792 Binder.restoreCallingIdentity(token);
6796 final void finishBooting() {
6797 synchronized (this) {
6798 if (!mBootAnimationComplete) {
6799 mCallFinishBooting = true;
6802 mCallFinishBooting = false;
6805 ArraySet<String> completedIsas = new ArraySet<String>();
6806 for (String abi : Build.SUPPORTED_ABIS) {
6807 Process.establishZygoteConnectionForAbi(abi);
6808 final String instructionSet = VMRuntime.getInstructionSet(abi);
6809 if (!completedIsas.contains(instructionSet)) {
6811 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6812 } catch (InstallerException e) {
6813 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6814 e.getMessage() +")");
6816 completedIsas.add(instructionSet);
6820 IntentFilter pkgFilter = new IntentFilter();
6821 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6822 pkgFilter.addDataScheme("package");
6823 mContext.registerReceiver(new BroadcastReceiver() {
6825 public void onReceive(Context context, Intent intent) {
6826 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6828 for (String pkg : pkgs) {
6829 synchronized (ActivityManagerService.this) {
6830 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6831 0, "query restart")) {
6832 setResultCode(Activity.RESULT_OK);
6841 IntentFilter dumpheapFilter = new IntentFilter();
6842 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6843 mContext.registerReceiver(new BroadcastReceiver() {
6845 public void onReceive(Context context, Intent intent) {
6846 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6847 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6849 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6854 // Let system services know.
6855 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6857 synchronized (this) {
6858 // Ensure that any processes we had put on hold are now started
6860 final int NP = mProcessesOnHold.size();
6862 ArrayList<ProcessRecord> procs =
6863 new ArrayList<ProcessRecord>(mProcessesOnHold);
6864 for (int ip=0; ip<NP; ip++) {
6865 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6867 startProcessLocked(procs.get(ip), "on-hold", null);
6871 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6872 // Start looking for apps that are abusing wake locks.
6873 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6874 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6875 // Tell anyone interested that we are done booting!
6876 SystemProperties.set("sys.boot_completed", "1");
6878 // And trigger dev.bootcomplete if we are not showing encryption progress
6879 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6880 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6881 SystemProperties.set("dev.bootcomplete", "1");
6883 mUserController.sendBootCompletedLocked(
6884 new IIntentReceiver.Stub() {
6886 public void performReceive(Intent intent, int resultCode,
6887 String data, Bundle extras, boolean ordered,
6888 boolean sticky, int sendingUser) {
6889 synchronized (ActivityManagerService.this) {
6890 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6895 scheduleStartProfilesLocked();
6901 public void bootAnimationComplete() {
6902 final boolean callFinishBooting;
6903 synchronized (this) {
6904 callFinishBooting = mCallFinishBooting;
6905 mBootAnimationComplete = true;
6907 if (callFinishBooting) {
6908 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6910 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6914 final void ensureBootCompleted() {
6916 boolean enableScreen;
6917 synchronized (this) {
6920 enableScreen = !mBooted;
6925 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6927 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6931 enableScreenAfterBoot();
6936 public final void activityResumed(IBinder token) {
6937 final long origId = Binder.clearCallingIdentity();
6938 synchronized(this) {
6939 ActivityStack stack = ActivityRecord.getStackLocked(token);
6940 if (stack != null) {
6941 stack.activityResumedLocked(token);
6944 Binder.restoreCallingIdentity(origId);
6948 public final void activityPaused(IBinder token) {
6949 final long origId = Binder.clearCallingIdentity();
6950 synchronized(this) {
6951 ActivityStack stack = ActivityRecord.getStackLocked(token);
6952 if (stack != null) {
6953 stack.activityPausedLocked(token, false);
6956 Binder.restoreCallingIdentity(origId);
6960 public final void activityStopped(IBinder token, Bundle icicle,
6961 PersistableBundle persistentState, CharSequence description) {
6962 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6964 // Refuse possible leaked file descriptors
6965 if (icicle != null && icicle.hasFileDescriptors()) {
6966 throw new IllegalArgumentException("File descriptors passed in Bundle");
6969 final long origId = Binder.clearCallingIdentity();
6971 synchronized (this) {
6972 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6974 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6980 Binder.restoreCallingIdentity(origId);
6984 public final void activityDestroyed(IBinder token) {
6985 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6986 synchronized (this) {
6987 ActivityStack stack = ActivityRecord.getStackLocked(token);
6988 if (stack != null) {
6989 stack.activityDestroyedLocked(token, "activityDestroyed");
6995 public final void activityRelaunched(IBinder token) {
6996 final long origId = Binder.clearCallingIdentity();
6997 synchronized (this) {
6998 mStackSupervisor.activityRelaunchedLocked(token);
7000 Binder.restoreCallingIdentity(origId);
7004 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7005 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7006 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7007 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7008 synchronized (this) {
7009 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7010 if (record == null) {
7011 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7012 + "found for: " + token);
7014 record.setSizeConfigurations(horizontalSizeConfiguration,
7015 verticalSizeConfigurations, smallestSizeConfigurations);
7020 public final void backgroundResourcesReleased(IBinder token) {
7021 final long origId = Binder.clearCallingIdentity();
7023 synchronized (this) {
7024 ActivityStack stack = ActivityRecord.getStackLocked(token);
7025 if (stack != null) {
7026 stack.backgroundResourcesReleased();
7030 Binder.restoreCallingIdentity(origId);
7035 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7036 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7040 public final void notifyEnterAnimationComplete(IBinder token) {
7041 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7045 public String getCallingPackage(IBinder token) {
7046 synchronized (this) {
7047 ActivityRecord r = getCallingRecordLocked(token);
7048 return r != null ? r.info.packageName : null;
7053 public ComponentName getCallingActivity(IBinder token) {
7054 synchronized (this) {
7055 ActivityRecord r = getCallingRecordLocked(token);
7056 return r != null ? r.intent.getComponent() : null;
7060 private ActivityRecord getCallingRecordLocked(IBinder token) {
7061 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7069 public ComponentName getActivityClassForToken(IBinder token) {
7070 synchronized(this) {
7071 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7075 return r.intent.getComponent();
7080 public String getPackageForToken(IBinder token) {
7081 synchronized(this) {
7082 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7086 return r.packageName;
7091 public boolean isRootVoiceInteraction(IBinder token) {
7092 synchronized(this) {
7093 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7097 return r.rootVoiceInteraction;
7102 public IIntentSender getIntentSender(int type,
7103 String packageName, IBinder token, String resultWho,
7104 int requestCode, Intent[] intents, String[] resolvedTypes,
7105 int flags, Bundle bOptions, int userId) {
7106 enforceNotIsolatedCaller("getIntentSender");
7107 // Refuse possible leaked file descriptors
7108 if (intents != null) {
7109 if (intents.length < 1) {
7110 throw new IllegalArgumentException("Intents array length must be >= 1");
7112 for (int i=0; i<intents.length; i++) {
7113 Intent intent = intents[i];
7114 if (intent != null) {
7115 if (intent.hasFileDescriptors()) {
7116 throw new IllegalArgumentException("File descriptors passed in Intent");
7118 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7119 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7120 throw new IllegalArgumentException(
7121 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7123 intents[i] = new Intent(intent);
7126 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7127 throw new IllegalArgumentException(
7128 "Intent array length does not match resolvedTypes length");
7131 if (bOptions != null) {
7132 if (bOptions.hasFileDescriptors()) {
7133 throw new IllegalArgumentException("File descriptors passed in options");
7137 synchronized(this) {
7138 int callingUid = Binder.getCallingUid();
7139 int origUserId = userId;
7140 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7141 type == ActivityManager.INTENT_SENDER_BROADCAST,
7142 ALLOW_NON_FULL, "getIntentSender", null);
7143 if (origUserId == UserHandle.USER_CURRENT) {
7144 // We don't want to evaluate this until the pending intent is
7145 // actually executed. However, we do want to always do the
7146 // security checking for it above.
7147 userId = UserHandle.USER_CURRENT;
7150 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7151 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7152 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7153 if (!UserHandle.isSameApp(callingUid, uid)) {
7154 String msg = "Permission Denial: getIntentSender() from pid="
7155 + Binder.getCallingPid()
7156 + ", uid=" + Binder.getCallingUid()
7157 + ", (need uid=" + uid + ")"
7158 + " is not allowed to send as package " + packageName;
7160 throw new SecurityException(msg);
7164 return getIntentSenderLocked(type, packageName, callingUid, userId,
7165 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7167 } catch (RemoteException e) {
7168 throw new SecurityException(e);
7173 IIntentSender getIntentSenderLocked(int type, String packageName,
7174 int callingUid, int userId, IBinder token, String resultWho,
7175 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7177 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7178 ActivityRecord activity = null;
7179 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7180 activity = ActivityRecord.isInStackLocked(token);
7181 if (activity == null) {
7182 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7185 if (activity.finishing) {
7186 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7191 // We're going to be splicing together extras before sending, so we're
7192 // okay poking into any contained extras.
7193 if (intents != null) {
7194 for (int i = 0; i < intents.length; i++) {
7195 intents[i].setDefusable(true);
7198 Bundle.setDefusable(bOptions, true);
7200 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7201 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7202 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7203 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7204 |PendingIntent.FLAG_UPDATE_CURRENT);
7206 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7207 type, packageName, activity, resultWho,
7208 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7209 WeakReference<PendingIntentRecord> ref;
7210 ref = mIntentSenderRecords.get(key);
7211 PendingIntentRecord rec = ref != null ? ref.get() : null;
7213 if (!cancelCurrent) {
7214 if (updateCurrent) {
7215 if (rec.key.requestIntent != null) {
7216 rec.key.requestIntent.replaceExtras(intents != null ?
7217 intents[intents.length - 1] : null);
7219 if (intents != null) {
7220 intents[intents.length-1] = rec.key.requestIntent;
7221 rec.key.allIntents = intents;
7222 rec.key.allResolvedTypes = resolvedTypes;
7224 rec.key.allIntents = null;
7225 rec.key.allResolvedTypes = null;
7230 rec.canceled = true;
7231 mIntentSenderRecords.remove(key);
7236 rec = new PendingIntentRecord(this, key, callingUid);
7237 mIntentSenderRecords.put(key, rec.ref);
7238 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7239 if (activity.pendingResults == null) {
7240 activity.pendingResults
7241 = new HashSet<WeakReference<PendingIntentRecord>>();
7243 activity.pendingResults.add(rec.ref);
7249 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7250 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7251 if (target instanceof PendingIntentRecord) {
7252 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7253 finishedReceiver, requiredPermission, options);
7255 if (intent == null) {
7256 // Weird case: someone has given us their own custom IIntentSender, and now
7257 // they have someone else trying to send to it but of course this isn't
7258 // really a PendingIntent, so there is no base Intent, and the caller isn't
7259 // supplying an Intent... but we never want to dispatch a null Intent to
7260 // a receiver, so um... let's make something up.
7261 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7262 intent = new Intent(Intent.ACTION_MAIN);
7265 target.send(code, intent, resolvedType, null, requiredPermission, options);
7266 } catch (RemoteException e) {
7268 // Platform code can rely on getting a result back when the send is done, but if
7269 // this intent sender is from outside of the system we can't rely on it doing that.
7270 // So instead we don't give it the result receiver, and instead just directly
7271 // report the finish immediately.
7272 if (finishedReceiver != null) {
7274 finishedReceiver.performReceive(intent, 0,
7275 null, null, false, false, UserHandle.getCallingUserId());
7276 } catch (RemoteException e) {
7284 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7286 * <p>{@code callerUid} must be allowed to request such whitelist by calling
7287 * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7289 void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7290 if (DEBUG_WHITELISTS) {
7291 Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7292 + targetUid + ", " + duration + ")");
7294 synchronized (mPidsSelfLocked) {
7295 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7297 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7300 if (!pr.whitelistManager) {
7301 if (DEBUG_WHITELISTS) {
7302 Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7303 + callerPid + " is not allowed");
7309 final long token = Binder.clearCallingIdentity();
7311 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7312 true, "pe from uid:" + callerUid);
7314 Binder.restoreCallingIdentity(token);
7319 public void cancelIntentSender(IIntentSender sender) {
7320 if (!(sender instanceof PendingIntentRecord)) {
7323 synchronized(this) {
7324 PendingIntentRecord rec = (PendingIntentRecord)sender;
7326 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7327 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7328 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7329 String msg = "Permission Denial: cancelIntentSender() from pid="
7330 + Binder.getCallingPid()
7331 + ", uid=" + Binder.getCallingUid()
7332 + " is not allowed to cancel packges "
7333 + rec.key.packageName;
7335 throw new SecurityException(msg);
7337 } catch (RemoteException e) {
7338 throw new SecurityException(e);
7340 cancelIntentSenderLocked(rec, true);
7344 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7345 rec.canceled = true;
7346 mIntentSenderRecords.remove(rec.key);
7347 if (cleanActivity && rec.key.activity != null) {
7348 rec.key.activity.pendingResults.remove(rec.ref);
7353 public String getPackageForIntentSender(IIntentSender pendingResult) {
7354 if (!(pendingResult instanceof PendingIntentRecord)) {
7358 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7359 return res.key.packageName;
7360 } catch (ClassCastException e) {
7366 public int getUidForIntentSender(IIntentSender sender) {
7367 if (sender instanceof PendingIntentRecord) {
7369 PendingIntentRecord res = (PendingIntentRecord)sender;
7371 } catch (ClassCastException e) {
7378 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7379 if (!(pendingResult instanceof PendingIntentRecord)) {
7383 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7384 if (res.key.allIntents == null) {
7387 for (int i=0; i<res.key.allIntents.length; i++) {
7388 Intent intent = res.key.allIntents[i];
7389 if (intent.getPackage() != null && intent.getComponent() != null) {
7394 } catch (ClassCastException e) {
7400 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7401 if (!(pendingResult instanceof PendingIntentRecord)) {
7405 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7406 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7410 } catch (ClassCastException e) {
7416 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7417 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7418 "getIntentForIntentSender()");
7419 if (!(pendingResult instanceof PendingIntentRecord)) {
7423 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7424 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7425 } catch (ClassCastException e) {
7431 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7432 if (!(pendingResult instanceof PendingIntentRecord)) {
7436 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7437 synchronized (this) {
7438 return getTagForIntentSenderLocked(res, prefix);
7440 } catch (ClassCastException e) {
7445 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7446 final Intent intent = res.key.requestIntent;
7447 if (intent != null) {
7448 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7449 || res.lastTagPrefix.equals(prefix))) {
7452 res.lastTagPrefix = prefix;
7453 final StringBuilder sb = new StringBuilder(128);
7454 if (prefix != null) {
7457 if (intent.getAction() != null) {
7458 sb.append(intent.getAction());
7459 } else if (intent.getComponent() != null) {
7460 intent.getComponent().appendShortString(sb);
7464 return res.lastTag = sb.toString();
7470 public void setProcessLimit(int max) {
7471 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7472 "setProcessLimit()");
7473 synchronized (this) {
7474 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7475 mProcessLimitOverride = max;
7481 public int getProcessLimit() {
7482 synchronized (this) {
7483 return mProcessLimitOverride;
7487 void foregroundTokenDied(ForegroundToken token) {
7488 synchronized (ActivityManagerService.this) {
7489 synchronized (mPidsSelfLocked) {
7491 = mForegroundProcesses.get(token.pid);
7495 mForegroundProcesses.remove(token.pid);
7496 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7500 pr.forcingToForeground = null;
7501 updateProcessForegroundLocked(pr, false, false);
7503 updateOomAdjLocked();
7508 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7509 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7510 "setProcessForeground()");
7511 synchronized(this) {
7512 boolean changed = false;
7514 synchronized (mPidsSelfLocked) {
7515 ProcessRecord pr = mPidsSelfLocked.get(pid);
7516 if (pr == null && isForeground) {
7517 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7520 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7521 if (oldToken != null) {
7522 oldToken.token.unlinkToDeath(oldToken, 0);
7523 mForegroundProcesses.remove(pid);
7525 pr.forcingToForeground = null;
7529 if (isForeground && token != null) {
7530 ForegroundToken newToken = new ForegroundToken() {
7532 public void binderDied() {
7533 foregroundTokenDied(this);
7537 newToken.token = token;
7539 token.linkToDeath(newToken, 0);
7540 mForegroundProcesses.put(pid, newToken);
7541 pr.forcingToForeground = token;
7543 } catch (RemoteException e) {
7544 // If the process died while doing this, we will later
7545 // do the cleanup with the process death link.
7551 updateOomAdjLocked();
7557 public boolean isAppForeground(int uid) throws RemoteException {
7558 synchronized (this) {
7559 UidRecord uidRec = mActiveUids.get(uid);
7560 if (uidRec == null || uidRec.idle) {
7563 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7567 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7568 // be guarded by permission checking.
7569 int getUidState(int uid) {
7570 synchronized (this) {
7571 UidRecord uidRec = mActiveUids.get(uid);
7572 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7577 public boolean isInMultiWindowMode(IBinder token) {
7578 final long origId = Binder.clearCallingIdentity();
7580 synchronized(this) {
7581 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7585 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7586 return !r.task.mFullscreen;
7589 Binder.restoreCallingIdentity(origId);
7594 public boolean isInPictureInPictureMode(IBinder token) {
7595 final long origId = Binder.clearCallingIdentity();
7597 synchronized(this) {
7598 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7599 if (stack == null) {
7602 return stack.mStackId == PINNED_STACK_ID;
7605 Binder.restoreCallingIdentity(origId);
7610 public void enterPictureInPictureMode(IBinder token) {
7611 final long origId = Binder.clearCallingIdentity();
7613 synchronized(this) {
7614 if (!mSupportsPictureInPicture) {
7615 throw new IllegalStateException("enterPictureInPictureMode: "
7616 + "Device doesn't support picture-in-picture mode.");
7619 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7622 throw new IllegalStateException("enterPictureInPictureMode: "
7623 + "Can't find activity for token=" + token);
7626 if (!r.supportsPictureInPicture()) {
7627 throw new IllegalArgumentException("enterPictureInPictureMode: "
7628 + "Picture-In-Picture not supported for r=" + r);
7631 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7633 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7634 final Rect bounds = (pinnedStack != null)
7635 ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7637 mStackSupervisor.moveActivityToPinnedStackLocked(
7638 r, "enterPictureInPictureMode", bounds);
7641 Binder.restoreCallingIdentity(origId);
7645 // =========================================================
7647 // =========================================================
7649 static class ProcessInfoService extends IProcessInfoService.Stub {
7650 final ActivityManagerService mActivityManagerService;
7651 ProcessInfoService(ActivityManagerService activityManagerService) {
7652 mActivityManagerService = activityManagerService;
7656 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7657 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7658 /*in*/ pids, /*out*/ states, null);
7662 public void getProcessStatesAndOomScoresFromPids(
7663 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7664 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7665 /*in*/ pids, /*out*/ states, /*out*/ scores);
7670 * For each PID in the given input array, write the current process state
7671 * for that process into the states array, or -1 to indicate that no
7672 * process with the given PID exists. If scores array is provided, write
7673 * the oom score for the process into the scores array, with INVALID_ADJ
7674 * indicating the PID doesn't exist.
7676 public void getProcessStatesAndOomScoresForPIDs(
7677 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7678 if (scores != null) {
7679 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7680 "getProcessStatesAndOomScoresForPIDs()");
7684 throw new NullPointerException("pids");
7685 } else if (states == null) {
7686 throw new NullPointerException("states");
7687 } else if (pids.length != states.length) {
7688 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7689 } else if (scores != null && pids.length != scores.length) {
7690 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7693 synchronized (mPidsSelfLocked) {
7694 for (int i = 0; i < pids.length; i++) {
7695 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7696 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7698 if (scores != null) {
7699 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7705 // =========================================================
7707 // =========================================================
7709 static class PermissionController extends IPermissionController.Stub {
7710 ActivityManagerService mActivityManagerService;
7711 PermissionController(ActivityManagerService activityManagerService) {
7712 mActivityManagerService = activityManagerService;
7716 public boolean checkPermission(String permission, int pid, int uid) {
7717 return mActivityManagerService.checkPermission(permission, pid,
7718 uid) == PackageManager.PERMISSION_GRANTED;
7722 public String[] getPackagesForUid(int uid) {
7723 return mActivityManagerService.mContext.getPackageManager()
7724 .getPackagesForUid(uid);
7728 public boolean isRuntimePermission(String permission) {
7730 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7731 .getPermissionInfo(permission, 0);
7732 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7733 } catch (NameNotFoundException nnfe) {
7734 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7740 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7742 public int checkComponentPermission(String permission, int pid, int uid,
7743 int owningUid, boolean exported) {
7744 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7745 owningUid, exported);
7749 public Object getAMSLock() {
7750 return ActivityManagerService.this;
7755 * This can be called with or without the global lock held.
7757 int checkComponentPermission(String permission, int pid, int uid,
7758 int owningUid, boolean exported) {
7759 if (pid == MY_PID) {
7760 return PackageManager.PERMISSION_GRANTED;
7762 return ActivityManager.checkComponentPermission(permission, uid,
7763 owningUid, exported);
7767 * As the only public entry point for permissions checking, this method
7768 * can enforce the semantic that requesting a check on a null global
7769 * permission is automatically denied. (Internally a null permission
7770 * string is used when calling {@link #checkComponentPermission} in cases
7771 * when only uid-based security is needed.)
7773 * This can be called with or without the global lock held.
7776 public int checkPermission(String permission, int pid, int uid) {
7777 if (permission == null) {
7778 return PackageManager.PERMISSION_DENIED;
7780 return checkComponentPermission(permission, pid, uid, -1, true);
7784 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7785 if (permission == null) {
7786 return PackageManager.PERMISSION_DENIED;
7789 // We might be performing an operation on behalf of an indirect binder
7790 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7791 // client identity accordingly before proceeding.
7792 Identity tlsIdentity = sCallerIdentity.get();
7793 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7794 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7795 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7796 uid = tlsIdentity.uid;
7797 pid = tlsIdentity.pid;
7800 return checkComponentPermission(permission, pid, uid, -1, true);
7804 * Binder IPC calls go through the public entry point.
7805 * This can be called with or without the global lock held.
7807 int checkCallingPermission(String permission) {
7808 return checkPermission(permission,
7809 Binder.getCallingPid(),
7810 UserHandle.getAppId(Binder.getCallingUid()));
7814 * This can be called with or without the global lock held.
7816 void enforceCallingPermission(String permission, String func) {
7817 if (checkCallingPermission(permission)
7818 == PackageManager.PERMISSION_GRANTED) {
7822 String msg = "Permission Denial: " + func + " from pid="
7823 + Binder.getCallingPid()
7824 + ", uid=" + Binder.getCallingUid()
7825 + " requires " + permission;
7827 throw new SecurityException(msg);
7831 * Determine if UID is holding permissions required to access {@link Uri} in
7832 * the given {@link ProviderInfo}. Final permission checking is always done
7833 * in {@link ContentProvider}.
7835 private final boolean checkHoldingPermissionsLocked(
7836 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7837 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7838 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7839 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7840 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7841 != PERMISSION_GRANTED) {
7845 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7848 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7849 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7850 if (pi.applicationInfo.uid == uid) {
7852 } else if (!pi.exported) {
7856 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7857 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7859 // check if target holds top-level <provider> permissions
7860 if (!readMet && pi.readPermission != null && considerUidPermissions
7861 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7864 if (!writeMet && pi.writePermission != null && considerUidPermissions
7865 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7869 // track if unprotected read/write is allowed; any denied
7870 // <path-permission> below removes this ability
7871 boolean allowDefaultRead = pi.readPermission == null;
7872 boolean allowDefaultWrite = pi.writePermission == null;
7874 // check if target holds any <path-permission> that match uri
7875 final PathPermission[] pps = pi.pathPermissions;
7877 final String path = grantUri.uri.getPath();
7879 while (i > 0 && (!readMet || !writeMet)) {
7881 PathPermission pp = pps[i];
7882 if (pp.match(path)) {
7884 final String pprperm = pp.getReadPermission();
7885 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7886 "Checking read perm for " + pprperm + " for " + pp.getPath()
7887 + ": match=" + pp.match(path)
7888 + " check=" + pm.checkUidPermission(pprperm, uid));
7889 if (pprperm != null) {
7890 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7891 == PERMISSION_GRANTED) {
7894 allowDefaultRead = false;
7899 final String ppwperm = pp.getWritePermission();
7900 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7901 "Checking write perm " + ppwperm + " for " + pp.getPath()
7902 + ": match=" + pp.match(path)
7903 + " check=" + pm.checkUidPermission(ppwperm, uid));
7904 if (ppwperm != null) {
7905 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7906 == PERMISSION_GRANTED) {
7909 allowDefaultWrite = false;
7917 // grant unprotected <provider> read/write, if not blocked by
7918 // <path-permission> above
7919 if (allowDefaultRead) readMet = true;
7920 if (allowDefaultWrite) writeMet = true;
7922 } catch (RemoteException e) {
7926 return readMet && writeMet;
7929 public int getAppStartMode(int uid, String packageName) {
7930 synchronized (this) {
7931 return checkAllowBackgroundLocked(uid, packageName, -1, true);
7935 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7936 boolean allowWhenForeground) {
7937 UidRecord uidRec = mActiveUids.get(uid);
7938 if (!mLenientBackgroundCheck) {
7939 if (!allowWhenForeground || uidRec == null
7940 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7941 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7942 packageName) != AppOpsManager.MODE_ALLOWED) {
7943 return ActivityManager.APP_START_MODE_DELAYED;
7947 } else if (uidRec == null || uidRec.idle) {
7948 if (callingPid >= 0) {
7950 synchronized (mPidsSelfLocked) {
7951 proc = mPidsSelfLocked.get(callingPid);
7953 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7954 // Whoever is instigating this is in the foreground, so we will allow it
7956 return ActivityManager.APP_START_MODE_NORMAL;
7959 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7960 != AppOpsManager.MODE_ALLOWED) {
7961 return ActivityManager.APP_START_MODE_DELAYED;
7964 return ActivityManager.APP_START_MODE_NORMAL;
7967 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7968 ProviderInfo pi = null;
7969 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7974 pi = AppGlobals.getPackageManager().resolveContentProvider(
7975 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7977 } catch (RemoteException ex) {
7983 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7984 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7985 if (targetUris != null) {
7986 return targetUris.get(grantUri);
7991 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7992 String targetPkg, int targetUid, GrantUri grantUri) {
7993 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7994 if (targetUris == null) {
7995 targetUris = Maps.newArrayMap();
7996 mGrantedUriPermissions.put(targetUid, targetUris);
7999 UriPermission perm = targetUris.get(grantUri);
8001 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8002 targetUris.put(grantUri, perm);
8008 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8009 final int modeFlags) {
8010 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8011 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8012 : UriPermission.STRENGTH_OWNED;
8014 // Root gets to do everything.
8019 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8020 if (perms == null) return false;
8022 // First look for exact match
8023 final UriPermission exactPerm = perms.get(grantUri);
8024 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8028 // No exact match, look for prefixes
8029 final int N = perms.size();
8030 for (int i = 0; i < N; i++) {
8031 final UriPermission perm = perms.valueAt(i);
8032 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8033 && perm.getStrength(modeFlags) >= minStrength) {
8042 * @param uri This uri must NOT contain an embedded userId.
8043 * @param userId The userId in which the uri is to be resolved.
8046 public int checkUriPermission(Uri uri, int pid, int uid,
8047 final int modeFlags, int userId, IBinder callerToken) {
8048 enforceNotIsolatedCaller("checkUriPermission");
8050 // Another redirected-binder-call permissions check as in
8051 // {@link checkPermissionWithToken}.
8052 Identity tlsIdentity = sCallerIdentity.get();
8053 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8054 uid = tlsIdentity.uid;
8055 pid = tlsIdentity.pid;
8058 // Our own process gets to do everything.
8059 if (pid == MY_PID) {
8060 return PackageManager.PERMISSION_GRANTED;
8062 synchronized (this) {
8063 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8064 ? PackageManager.PERMISSION_GRANTED
8065 : PackageManager.PERMISSION_DENIED;
8070 * Check if the targetPkg can be granted permission to access uri by
8071 * the callingUid using the given modeFlags. Throws a security exception
8072 * if callingUid is not allowed to do this. Returns the uid of the target
8073 * if the URI permission grant should be performed; returns -1 if it is not
8074 * needed (for example targetPkg already has permission to access the URI).
8075 * If you already know the uid of the target, you can supply it in
8076 * lastTargetUid else set that to -1.
8078 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8079 final int modeFlags, int lastTargetUid) {
8080 if (!Intent.isAccessUriMode(modeFlags)) {
8084 if (targetPkg != null) {
8085 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8086 "Checking grant " + targetPkg + " permission to " + grantUri);
8089 final IPackageManager pm = AppGlobals.getPackageManager();
8091 // If this is not a content: uri, we can't do anything with it.
8092 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8093 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8094 "Can't grant URI permission for non-content URI: " + grantUri);
8098 final String authority = grantUri.uri.getAuthority();
8099 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8100 MATCH_DEBUG_TRIAGED_MISSING);
8102 Slog.w(TAG, "No content provider found for permission check: " +
8103 grantUri.uri.toSafeString());
8107 int targetUid = lastTargetUid;
8108 if (targetUid < 0 && targetPkg != null) {
8110 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8111 UserHandle.getUserId(callingUid));
8112 if (targetUid < 0) {
8113 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8114 "Can't grant URI permission no uid for: " + targetPkg);
8117 } catch (RemoteException ex) {
8122 if (targetUid >= 0) {
8123 // First... does the target actually need this permission?
8124 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8125 // No need to grant the target this permission.
8126 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8127 "Target " + targetPkg + " already has full permission to " + grantUri);
8131 // First... there is no target package, so can anyone access it?
8132 boolean allowed = pi.exported;
8133 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8134 if (pi.readPermission != null) {
8138 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8139 if (pi.writePermission != null) {
8148 /* There is a special cross user grant if:
8149 * - The target is on another user.
8150 * - Apps on the current user can access the uri without any uid permissions.
8151 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8152 * grant uri permissions.
8154 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8155 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8156 modeFlags, false /*without considering the uid permissions*/);
8158 // Second... is the provider allowing granting of URI permissions?
8159 if (!specialCrossUserGrant) {
8160 if (!pi.grantUriPermissions) {
8161 throw new SecurityException("Provider " + pi.packageName
8163 + " does not allow granting of Uri permissions (uri "
8166 if (pi.uriPermissionPatterns != null) {
8167 final int N = pi.uriPermissionPatterns.length;
8168 boolean allowed = false;
8169 for (int i=0; i<N; i++) {
8170 if (pi.uriPermissionPatterns[i] != null
8171 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8177 throw new SecurityException("Provider " + pi.packageName
8179 + " does not allow granting of permission to path of Uri "
8185 // Third... does the caller itself have permission to access
8187 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8188 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8189 // Require they hold a strong enough Uri permission
8190 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8191 throw new SecurityException("Uid " + callingUid
8192 + " does not have permission to uri " + grantUri);
8200 * @param uri This uri must NOT contain an embedded userId.
8201 * @param userId The userId in which the uri is to be resolved.
8204 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8205 final int modeFlags, int userId) {
8206 enforceNotIsolatedCaller("checkGrantUriPermission");
8207 synchronized(this) {
8208 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8209 new GrantUri(userId, uri, false), modeFlags, -1);
8213 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8214 final int modeFlags, UriPermissionOwner owner) {
8215 if (!Intent.isAccessUriMode(modeFlags)) {
8219 // So here we are: the caller has the assumed permission
8220 // to the uri, and the target doesn't. Let's now give this to
8223 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8224 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8226 final String authority = grantUri.uri.getAuthority();
8227 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8228 MATCH_DEBUG_TRIAGED_MISSING);
8230 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8234 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8235 grantUri.prefix = true;
8237 final UriPermission perm = findOrCreateUriPermissionLocked(
8238 pi.packageName, targetPkg, targetUid, grantUri);
8239 perm.grantModes(modeFlags, owner);
8242 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8243 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8244 if (targetPkg == null) {
8245 throw new NullPointerException("targetPkg");
8248 final IPackageManager pm = AppGlobals.getPackageManager();
8250 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8251 } catch (RemoteException ex) {
8255 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8257 if (targetUid < 0) {
8261 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8265 static class NeededUriGrants extends ArrayList<GrantUri> {
8266 final String targetPkg;
8267 final int targetUid;
8270 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8271 this.targetPkg = targetPkg;
8272 this.targetUid = targetUid;
8278 * Like checkGrantUriPermissionLocked, but takes an Intent.
8280 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8281 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8282 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8283 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8284 + " clip=" + (intent != null ? intent.getClipData() : null)
8285 + " from " + intent + "; flags=0x"
8286 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8288 if (targetPkg == null) {
8289 throw new NullPointerException("targetPkg");
8292 if (intent == null) {
8295 Uri data = intent.getData();
8296 ClipData clip = intent.getClipData();
8297 if (data == null && clip == null) {
8300 // Default userId for uris in the intent (if they don't specify it themselves)
8301 int contentUserHint = intent.getContentUserHint();
8302 if (contentUserHint == UserHandle.USER_CURRENT) {
8303 contentUserHint = UserHandle.getUserId(callingUid);
8305 final IPackageManager pm = AppGlobals.getPackageManager();
8307 if (needed != null) {
8308 targetUid = needed.targetUid;
8311 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8313 } catch (RemoteException ex) {
8316 if (targetUid < 0) {
8317 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8318 "Can't grant URI permission no uid for: " + targetPkg
8319 + " on user " + targetUserId);
8324 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8325 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8327 if (targetUid > 0) {
8328 if (needed == null) {
8329 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8331 needed.add(grantUri);
8335 for (int i=0; i<clip.getItemCount(); i++) {
8336 Uri uri = clip.getItemAt(i).getUri();
8338 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8339 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8341 if (targetUid > 0) {
8342 if (needed == null) {
8343 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8345 needed.add(grantUri);
8348 Intent clipIntent = clip.getItemAt(i).getIntent();
8349 if (clipIntent != null) {
8350 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8351 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8352 if (newNeeded != null) {
8364 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8366 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8367 UriPermissionOwner owner) {
8368 if (needed != null) {
8369 for (int i=0; i<needed.size(); i++) {
8370 GrantUri grantUri = needed.get(i);
8371 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8372 grantUri, needed.flags, owner);
8377 void grantUriPermissionFromIntentLocked(int callingUid,
8378 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8379 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8380 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8381 if (needed == null) {
8385 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8389 * @param uri This uri must NOT contain an embedded userId.
8390 * @param userId The userId in which the uri is to be resolved.
8393 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8394 final int modeFlags, int userId) {
8395 enforceNotIsolatedCaller("grantUriPermission");
8396 GrantUri grantUri = new GrantUri(userId, uri, false);
8397 synchronized(this) {
8398 final ProcessRecord r = getRecordForAppLocked(caller);
8400 throw new SecurityException("Unable to find app for caller "
8402 + " when granting permission to uri " + grantUri);
8404 if (targetPkg == null) {
8405 throw new IllegalArgumentException("null target");
8407 if (grantUri == null) {
8408 throw new IllegalArgumentException("null uri");
8411 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8412 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8413 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8414 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8416 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8417 UserHandle.getUserId(r.uid));
8421 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8422 if (perm.modeFlags == 0) {
8423 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8425 if (perms != null) {
8426 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8427 "Removing " + perm.targetUid + " permission to " + perm.uri);
8429 perms.remove(perm.uri);
8430 if (perms.isEmpty()) {
8431 mGrantedUriPermissions.remove(perm.targetUid);
8437 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8438 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8439 "Revoking all granted permissions to " + grantUri);
8441 final IPackageManager pm = AppGlobals.getPackageManager();
8442 final String authority = grantUri.uri.getAuthority();
8443 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8444 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8446 Slog.w(TAG, "No content provider found for permission revoke: "
8447 + grantUri.toSafeString());
8451 // Does the caller have this permission on the URI?
8452 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8453 // If they don't have direct access to the URI, then revoke any
8454 // ownerless URI permissions that have been granted to them.
8455 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8456 if (perms != null) {
8457 boolean persistChanged = false;
8458 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8459 final UriPermission perm = it.next();
8460 if (perm.uri.sourceUserId == grantUri.sourceUserId
8461 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8462 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8463 "Revoking non-owned " + perm.targetUid
8464 + " permission to " + perm.uri);
8465 persistChanged |= perm.revokeModes(
8466 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8467 if (perm.modeFlags == 0) {
8472 if (perms.isEmpty()) {
8473 mGrantedUriPermissions.remove(callingUid);
8475 if (persistChanged) {
8476 schedulePersistUriGrants();
8482 boolean persistChanged = false;
8484 // Go through all of the permissions and remove any that match.
8485 int N = mGrantedUriPermissions.size();
8486 for (int i = 0; i < N; i++) {
8487 final int targetUid = mGrantedUriPermissions.keyAt(i);
8488 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8490 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8491 final UriPermission perm = it.next();
8492 if (perm.uri.sourceUserId == grantUri.sourceUserId
8493 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8494 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8495 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8496 persistChanged |= perm.revokeModes(
8497 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8498 if (perm.modeFlags == 0) {
8504 if (perms.isEmpty()) {
8505 mGrantedUriPermissions.remove(targetUid);
8511 if (persistChanged) {
8512 schedulePersistUriGrants();
8517 * @param uri This uri must NOT contain an embedded userId.
8518 * @param userId The userId in which the uri is to be resolved.
8521 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8523 enforceNotIsolatedCaller("revokeUriPermission");
8524 synchronized(this) {
8525 final ProcessRecord r = getRecordForAppLocked(caller);
8527 throw new SecurityException("Unable to find app for caller "
8529 + " when revoking permission to uri " + uri);
8532 Slog.w(TAG, "revokeUriPermission: null uri");
8536 if (!Intent.isAccessUriMode(modeFlags)) {
8540 final String authority = uri.getAuthority();
8541 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8542 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8544 Slog.w(TAG, "No content provider found for permission revoke: "
8545 + uri.toSafeString());
8549 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8554 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8557 * @param packageName Package name to match, or {@code null} to apply to all
8559 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8561 * @param persistable If persistable grants should be removed.
8563 private void removeUriPermissionsForPackageLocked(
8564 String packageName, int userHandle, boolean persistable) {
8565 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8566 throw new IllegalArgumentException("Must narrow by either package or user");
8569 boolean persistChanged = false;
8571 int N = mGrantedUriPermissions.size();
8572 for (int i = 0; i < N; i++) {
8573 final int targetUid = mGrantedUriPermissions.keyAt(i);
8574 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8576 // Only inspect grants matching user
8577 if (userHandle == UserHandle.USER_ALL
8578 || userHandle == UserHandle.getUserId(targetUid)) {
8579 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8580 final UriPermission perm = it.next();
8582 // Only inspect grants matching package
8583 if (packageName == null || perm.sourcePkg.equals(packageName)
8584 || perm.targetPkg.equals(packageName)) {
8585 // Hacky solution as part of fixing a security bug; ignore
8586 // grants associated with DownloadManager so we don't have
8587 // to immediately launch it to regrant the permissions
8588 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8589 && !persistable) continue;
8591 persistChanged |= perm.revokeModes(persistable
8592 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8594 // Only remove when no modes remain; any persisted grants
8595 // will keep this alive.
8596 if (perm.modeFlags == 0) {
8602 if (perms.isEmpty()) {
8603 mGrantedUriPermissions.remove(targetUid);
8610 if (persistChanged) {
8611 schedulePersistUriGrants();
8616 public IBinder newUriPermissionOwner(String name) {
8617 enforceNotIsolatedCaller("newUriPermissionOwner");
8618 synchronized(this) {
8619 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8620 return owner.getExternalTokenLocked();
8625 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8626 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8627 synchronized(this) {
8628 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8630 throw new IllegalArgumentException("Activity does not exist; token="
8633 return r.getUriPermissionsLocked().getExternalTokenLocked();
8637 * @param uri This uri must NOT contain an embedded userId.
8638 * @param sourceUserId The userId in which the uri is to be resolved.
8639 * @param targetUserId The userId of the app that receives the grant.
8642 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8643 final int modeFlags, int sourceUserId, int targetUserId) {
8644 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8645 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8646 "grantUriPermissionFromOwner", null);
8647 synchronized(this) {
8648 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8649 if (owner == null) {
8650 throw new IllegalArgumentException("Unknown owner: " + token);
8652 if (fromUid != Binder.getCallingUid()) {
8653 if (Binder.getCallingUid() != Process.myUid()) {
8654 // Only system code can grant URI permissions on behalf
8656 throw new SecurityException("nice try");
8659 if (targetPkg == null) {
8660 throw new IllegalArgumentException("null target");
8663 throw new IllegalArgumentException("null uri");
8666 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8667 modeFlags, owner, targetUserId);
8672 * @param uri This uri must NOT contain an embedded userId.
8673 * @param userId The userId in which the uri is to be resolved.
8676 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8677 synchronized(this) {
8678 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8679 if (owner == null) {
8680 throw new IllegalArgumentException("Unknown owner: " + token);
8684 owner.removeUriPermissionsLocked(mode);
8686 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8687 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8692 private void schedulePersistUriGrants() {
8693 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8694 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8695 10 * DateUtils.SECOND_IN_MILLIS);
8699 private void writeGrantedUriPermissions() {
8700 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8702 // Snapshot permissions so we can persist without lock
8703 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8704 synchronized (this) {
8705 final int size = mGrantedUriPermissions.size();
8706 for (int i = 0; i < size; i++) {
8707 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8708 for (UriPermission perm : perms.values()) {
8709 if (perm.persistedModeFlags != 0) {
8710 persist.add(perm.snapshot());
8716 FileOutputStream fos = null;
8718 fos = mGrantFile.startWrite();
8720 XmlSerializer out = new FastXmlSerializer();
8721 out.setOutput(fos, StandardCharsets.UTF_8.name());
8722 out.startDocument(null, true);
8723 out.startTag(null, TAG_URI_GRANTS);
8724 for (UriPermission.Snapshot perm : persist) {
8725 out.startTag(null, TAG_URI_GRANT);
8726 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8727 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8728 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8729 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8730 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8731 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8732 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8733 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8734 out.endTag(null, TAG_URI_GRANT);
8736 out.endTag(null, TAG_URI_GRANTS);
8739 mGrantFile.finishWrite(fos);
8740 } catch (IOException e) {
8742 mGrantFile.failWrite(fos);
8747 private void readGrantedUriPermissionsLocked() {
8748 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8750 final long now = System.currentTimeMillis();
8752 FileInputStream fis = null;
8754 fis = mGrantFile.openRead();
8755 final XmlPullParser in = Xml.newPullParser();
8756 in.setInput(fis, StandardCharsets.UTF_8.name());
8759 while ((type = in.next()) != END_DOCUMENT) {
8760 final String tag = in.getName();
8761 if (type == START_TAG) {
8762 if (TAG_URI_GRANT.equals(tag)) {
8763 final int sourceUserId;
8764 final int targetUserId;
8765 final int userHandle = readIntAttribute(in,
8766 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8767 if (userHandle != UserHandle.USER_NULL) {
8768 // For backwards compatibility.
8769 sourceUserId = userHandle;
8770 targetUserId = userHandle;
8772 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8773 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8775 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8776 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8777 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8778 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8779 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8780 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8782 // Sanity check that provider still belongs to source package
8783 // Both direct boot aware and unaware packages are fine as we
8784 // will do filtering at query time to avoid multiple parsing.
8785 final ProviderInfo pi = getProviderInfoLocked(
8786 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8787 | MATCH_DIRECT_BOOT_UNAWARE);
8788 if (pi != null && sourcePkg.equals(pi.packageName)) {
8791 targetUid = AppGlobals.getPackageManager().getPackageUid(
8792 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8793 } catch (RemoteException e) {
8795 if (targetUid != -1) {
8796 final UriPermission perm = findOrCreateUriPermissionLocked(
8797 sourcePkg, targetPkg, targetUid,
8798 new GrantUri(sourceUserId, uri, prefix));
8799 perm.initPersistedModes(modeFlags, createdTime);
8802 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8803 + " but instead found " + pi);
8808 } catch (FileNotFoundException e) {
8809 // Missing grants is okay
8810 } catch (IOException e) {
8811 Slog.wtf(TAG, "Failed reading Uri grants", e);
8812 } catch (XmlPullParserException e) {
8813 Slog.wtf(TAG, "Failed reading Uri grants", e);
8815 IoUtils.closeQuietly(fis);
8820 * @param uri This uri must NOT contain an embedded userId.
8821 * @param userId The userId in which the uri is to be resolved.
8824 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8825 enforceNotIsolatedCaller("takePersistableUriPermission");
8827 Preconditions.checkFlagsArgument(modeFlags,
8828 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8830 synchronized (this) {
8831 final int callingUid = Binder.getCallingUid();
8832 boolean persistChanged = false;
8833 GrantUri grantUri = new GrantUri(userId, uri, false);
8835 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8836 new GrantUri(userId, uri, false));
8837 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8838 new GrantUri(userId, uri, true));
8840 final boolean exactValid = (exactPerm != null)
8841 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8842 final boolean prefixValid = (prefixPerm != null)
8843 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8845 if (!(exactValid || prefixValid)) {
8846 throw new SecurityException("No persistable permission grants found for UID "
8847 + callingUid + " and Uri " + grantUri.toSafeString());
8851 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8854 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8857 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8859 if (persistChanged) {
8860 schedulePersistUriGrants();
8866 * @param uri This uri must NOT contain an embedded userId.
8867 * @param userId The userId in which the uri is to be resolved.
8870 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8871 enforceNotIsolatedCaller("releasePersistableUriPermission");
8873 Preconditions.checkFlagsArgument(modeFlags,
8874 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8876 synchronized (this) {
8877 final int callingUid = Binder.getCallingUid();
8878 boolean persistChanged = false;
8880 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8881 new GrantUri(userId, uri, false));
8882 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8883 new GrantUri(userId, uri, true));
8884 if (exactPerm == null && prefixPerm == null) {
8885 throw new SecurityException("No permission grants found for UID " + callingUid
8886 + " and Uri " + uri.toSafeString());
8889 if (exactPerm != null) {
8890 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8891 removeUriPermissionIfNeededLocked(exactPerm);
8893 if (prefixPerm != null) {
8894 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8895 removeUriPermissionIfNeededLocked(prefixPerm);
8898 if (persistChanged) {
8899 schedulePersistUriGrants();
8905 * Prune any older {@link UriPermission} for the given UID until outstanding
8906 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8908 * @return if any mutations occured that require persisting.
8910 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8911 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8912 if (perms == null) return false;
8913 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8915 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8916 for (UriPermission perm : perms.values()) {
8917 if (perm.persistedModeFlags != 0) {
8918 persisted.add(perm);
8922 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8923 if (trimCount <= 0) return false;
8925 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8926 for (int i = 0; i < trimCount; i++) {
8927 final UriPermission perm = persisted.get(i);
8929 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8930 "Trimming grant created at " + perm.persistedCreateTime);
8932 perm.releasePersistableModes(~0);
8933 removeUriPermissionIfNeededLocked(perm);
8940 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8941 String packageName, boolean incoming) {
8942 enforceNotIsolatedCaller("getPersistedUriPermissions");
8943 Preconditions.checkNotNull(packageName, "packageName");
8945 final int callingUid = Binder.getCallingUid();
8946 final int callingUserId = UserHandle.getUserId(callingUid);
8947 final IPackageManager pm = AppGlobals.getPackageManager();
8949 final int packageUid = pm.getPackageUid(packageName,
8950 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8951 if (packageUid != callingUid) {
8952 throw new SecurityException(
8953 "Package " + packageName + " does not belong to calling UID " + callingUid);
8955 } catch (RemoteException e) {
8956 throw new SecurityException("Failed to verify package name ownership");
8959 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8960 synchronized (this) {
8962 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8964 if (perms == null) {
8965 Slog.w(TAG, "No permission grants found for " + packageName);
8967 for (UriPermission perm : perms.values()) {
8968 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8969 result.add(perm.buildPersistedPublicApiObject());
8974 final int size = mGrantedUriPermissions.size();
8975 for (int i = 0; i < size; i++) {
8976 final ArrayMap<GrantUri, UriPermission> perms =
8977 mGrantedUriPermissions.valueAt(i);
8978 for (UriPermission perm : perms.values()) {
8979 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8980 result.add(perm.buildPersistedPublicApiObject());
8986 return new ParceledListSlice<android.content.UriPermission>(result);
8990 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8991 String packageName, int userId) {
8992 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8993 "getGrantedUriPermissions");
8995 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8996 synchronized (this) {
8997 final int size = mGrantedUriPermissions.size();
8998 for (int i = 0; i < size; i++) {
8999 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9000 for (UriPermission perm : perms.values()) {
9001 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9002 && perm.persistedModeFlags != 0) {
9003 result.add(perm.buildPersistedPublicApiObject());
9008 return new ParceledListSlice<android.content.UriPermission>(result);
9012 public void clearGrantedUriPermissions(String packageName, int userId) {
9013 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9014 "clearGrantedUriPermissions");
9015 removeUriPermissionsForPackageLocked(packageName, userId, true);
9019 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9020 synchronized (this) {
9022 who != null ? getRecordForAppLocked(who) : null;
9023 if (app == null) return;
9025 Message msg = Message.obtain();
9026 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9028 msg.arg1 = waiting ? 1 : 0;
9029 mUiHandler.sendMessage(msg);
9034 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9035 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9036 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9037 outInfo.availMem = Process.getFreeMemory();
9038 outInfo.totalMem = Process.getTotalMemory();
9039 outInfo.threshold = homeAppMem;
9040 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9041 outInfo.hiddenAppThreshold = cachedAppMem;
9042 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9043 ProcessList.SERVICE_ADJ);
9044 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9045 ProcessList.VISIBLE_APP_ADJ);
9046 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9047 ProcessList.FOREGROUND_APP_ADJ);
9050 // =========================================================
9052 // =========================================================
9055 public List<IAppTask> getAppTasks(String callingPackage) {
9056 int callingUid = Binder.getCallingUid();
9057 long ident = Binder.clearCallingIdentity();
9059 synchronized(this) {
9060 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9062 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9064 final int N = mRecentTasks.size();
9065 for (int i = 0; i < N; i++) {
9066 TaskRecord tr = mRecentTasks.get(i);
9067 // Skip tasks that do not match the caller. We don't need to verify
9068 // callingPackage, because we are also limiting to callingUid and know
9069 // that will limit to the correct security sandbox.
9070 if (tr.effectiveUid != callingUid) {
9073 Intent intent = tr.getBaseIntent();
9074 if (intent == null ||
9075 !callingPackage.equals(intent.getComponent().getPackageName())) {
9078 ActivityManager.RecentTaskInfo taskInfo =
9079 createRecentTaskInfoFromTaskRecord(tr);
9080 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9084 Binder.restoreCallingIdentity(ident);
9091 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9092 final int callingUid = Binder.getCallingUid();
9093 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9095 synchronized(this) {
9096 if (DEBUG_ALL) Slog.v(
9097 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9099 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9102 // TODO: Improve with MRU list from all ActivityStacks.
9103 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9110 * Creates a new RecentTaskInfo from a TaskRecord.
9112 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9113 // Update the task description to reflect any changes in the task stack
9114 tr.updateTaskDescription();
9116 // Compose the recent task info
9117 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9118 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9119 rti.persistentId = tr.taskId;
9120 rti.baseIntent = new Intent(tr.getBaseIntent());
9121 rti.origActivity = tr.origActivity;
9122 rti.realActivity = tr.realActivity;
9123 rti.description = tr.lastDescription;
9124 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9125 rti.userId = tr.userId;
9126 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9127 rti.firstActiveTime = tr.firstActiveTime;
9128 rti.lastActiveTime = tr.lastActiveTime;
9129 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9130 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9131 rti.numActivities = 0;
9132 if (tr.mBounds != null) {
9133 rti.bounds = new Rect(tr.mBounds);
9135 rti.isDockable = tr.canGoInDockedStack();
9136 rti.resizeMode = tr.mResizeMode;
9138 ActivityRecord base = null;
9139 ActivityRecord top = null;
9142 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9143 tmp = tr.mActivities.get(i);
9144 if (tmp.finishing) {
9148 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9151 rti.numActivities++;
9154 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9155 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9160 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9161 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9162 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9164 if (checkPermission(android.Manifest.permission.GET_TASKS,
9165 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9166 // Temporary compatibility: some existing apps on the system image may
9167 // still be requesting the old permission and not switched to the new
9168 // one; if so, we'll still allow them full access. This means we need
9169 // to see if they are holding the old permission and are a system app.
9171 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9173 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9174 + " is using old GET_TASKS but privileged; allowing");
9176 } catch (RemoteException e) {
9181 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9182 + " does not hold REAL_GET_TASKS; limiting output");
9188 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9190 final int callingUid = Binder.getCallingUid();
9191 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9192 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9194 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9195 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9196 synchronized (this) {
9197 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9199 final boolean detailed = checkCallingPermission(
9200 android.Manifest.permission.GET_DETAILED_TASKS)
9201 == PackageManager.PERMISSION_GRANTED;
9203 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9204 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9205 return ParceledListSlice.emptyList();
9207 mRecentTasks.loadUserRecentsLocked(userId);
9209 final int recentsCount = mRecentTasks.size();
9210 ArrayList<ActivityManager.RecentTaskInfo> res =
9211 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9213 final Set<Integer> includedUsers;
9214 if (includeProfiles) {
9215 includedUsers = mUserController.getProfileIds(userId);
9217 includedUsers = new HashSet<>();
9219 includedUsers.add(Integer.valueOf(userId));
9221 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9222 TaskRecord tr = mRecentTasks.get(i);
9223 // Only add calling user or related users recent tasks
9224 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9225 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9229 if (tr.realActivitySuspended) {
9230 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9234 // Return the entry if desired by the caller. We always return
9235 // the first entry, because callers always expect this to be the
9236 // foreground app. We may filter others if the caller has
9237 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9238 // we should exclude the entry.
9242 || (tr.intent == null)
9243 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9246 // If the caller doesn't have the GET_TASKS permission, then only
9247 // allow them to see a small subset of tasks -- their own and home.
9248 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9249 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9253 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9254 if (tr.stack != null && tr.stack.isHomeStack()) {
9255 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9256 "Skipping, home stack task: " + tr);
9260 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9261 final ActivityStack stack = tr.stack;
9262 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9263 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9264 "Skipping, top task in docked stack: " + tr);
9268 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9269 if (tr.stack != null && tr.stack.isPinnedStack()) {
9270 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9271 "Skipping, pinned stack task: " + tr);
9275 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9276 // Don't include auto remove tasks that are finished or finishing.
9277 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9278 "Skipping, auto-remove without activity: " + tr);
9281 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9282 && !tr.isAvailable) {
9283 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9284 "Skipping, unavail real act: " + tr);
9288 if (!tr.mUserSetupComplete) {
9289 // Don't include task launched while user is not done setting-up.
9290 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9291 "Skipping, user setup not complete: " + tr);
9295 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9297 rti.baseIntent.replaceExtras((Bundle)null);
9304 return new ParceledListSlice<>(res);
9309 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9310 synchronized (this) {
9311 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9312 "getTaskThumbnail()");
9313 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9314 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9316 return tr.getTaskThumbnailLocked();
9323 public int addAppTask(IBinder activityToken, Intent intent,
9324 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9325 final int callingUid = Binder.getCallingUid();
9326 final long callingIdent = Binder.clearCallingIdentity();
9329 synchronized (this) {
9330 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9332 throw new IllegalArgumentException("Activity does not exist; token="
9335 ComponentName comp = intent.getComponent();
9337 throw new IllegalArgumentException("Intent " + intent
9338 + " must specify explicit component");
9340 if (thumbnail.getWidth() != mThumbnailWidth
9341 || thumbnail.getHeight() != mThumbnailHeight) {
9342 throw new IllegalArgumentException("Bad thumbnail size: got "
9343 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9344 + mThumbnailWidth + "x" + mThumbnailHeight);
9346 if (intent.getSelector() != null) {
9347 intent.setSelector(null);
9349 if (intent.getSourceBounds() != null) {
9350 intent.setSourceBounds(null);
9352 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9353 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9354 // The caller has added this as an auto-remove task... that makes no
9355 // sense, so turn off auto-remove.
9356 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9359 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9360 mLastAddedTaskActivity = null;
9362 ActivityInfo ainfo = mLastAddedTaskActivity;
9363 if (ainfo == null) {
9364 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9365 comp, 0, UserHandle.getUserId(callingUid));
9366 if (ainfo.applicationInfo.uid != callingUid) {
9367 throw new SecurityException(
9368 "Can't add task for another application: target uid="
9369 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9373 // Use the full screen as the context for the task thumbnail
9374 final Point displaySize = new Point();
9375 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9376 r.task.stack.getDisplaySize(displaySize);
9377 thumbnailInfo.taskWidth = displaySize.x;
9378 thumbnailInfo.taskHeight = displaySize.y;
9379 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9381 TaskRecord task = new TaskRecord(this,
9382 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9383 ainfo, intent, description, thumbnailInfo);
9385 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9387 // If this would have caused a trim, then we'll abort because that
9388 // means it would be added at the end of the list but then just removed.
9389 return INVALID_TASK_ID;
9392 final int N = mRecentTasks.size();
9393 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9394 final TaskRecord tr = mRecentTasks.remove(N - 1);
9395 tr.removedFromRecents();
9398 task.inRecents = true;
9399 mRecentTasks.add(task);
9400 r.task.stack.addTask(task, false, "addAppTask");
9402 task.setLastThumbnailLocked(thumbnail);
9403 task.freeLastThumbnail();
9408 Binder.restoreCallingIdentity(callingIdent);
9413 public Point getAppTaskThumbnailSize() {
9414 synchronized (this) {
9415 return new Point(mThumbnailWidth, mThumbnailHeight);
9420 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9421 synchronized (this) {
9422 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9424 r.setTaskDescription(td);
9425 r.task.updateTaskDescription();
9431 public void setTaskResizeable(int taskId, int resizeableMode) {
9432 synchronized (this) {
9433 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9434 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9436 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9439 if (task.mResizeMode != resizeableMode) {
9440 task.mResizeMode = resizeableMode;
9441 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9442 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9443 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9449 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9450 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9451 long ident = Binder.clearCallingIdentity();
9453 synchronized (this) {
9454 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9456 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9459 int stackId = task.stack.mStackId;
9460 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9461 // in crop windows resize mode or if the task size is affected by the docked stack
9462 // changing size. No need to update configuration.
9463 if (bounds != null && task.inCropWindowsResizeMode()
9464 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9465 mWindowManager.scrollTask(task.taskId, bounds);
9469 // Place the task in the right stack if it isn't there already based on
9470 // the requested bounds.
9471 // The stack transition logic is:
9472 // - a null bounds on a freeform task moves that task to fullscreen
9473 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9474 // that task to freeform
9475 // - otherwise the task is not moved
9476 if (!StackId.isTaskResizeAllowed(stackId)) {
9477 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9479 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9480 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9481 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9482 stackId = FREEFORM_WORKSPACE_STACK_ID;
9484 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9485 if (stackId != task.stack.mStackId) {
9486 mStackSupervisor.moveTaskToStackUncheckedLocked(
9487 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9488 preserveWindow = false;
9491 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9492 false /* deferResume */);
9495 Binder.restoreCallingIdentity(ident);
9500 public Rect getTaskBounds(int taskId) {
9501 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9502 long ident = Binder.clearCallingIdentity();
9503 Rect rect = new Rect();
9505 synchronized (this) {
9506 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9507 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9509 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9512 if (task.stack != null) {
9513 // Return the bounds from window manager since it will be adjusted for various
9514 // things like the presense of a docked stack for tasks that aren't resizeable.
9515 mWindowManager.getTaskBounds(task.taskId, rect);
9517 // Task isn't in window manager yet since it isn't associated with a stack.
9518 // Return the persist value from activity manager
9519 if (task.mBounds != null) {
9520 rect.set(task.mBounds);
9521 } else if (task.mLastNonFullscreenBounds != null) {
9522 rect.set(task.mLastNonFullscreenBounds);
9527 Binder.restoreCallingIdentity(ident);
9533 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9534 if (userId != UserHandle.getCallingUserId()) {
9535 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9536 "getTaskDescriptionIcon");
9538 final File passedIconFile = new File(filePath);
9539 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9540 passedIconFile.getName());
9541 if (!legitIconFile.getPath().equals(filePath)
9542 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9543 throw new IllegalArgumentException("Bad file path: " + filePath
9544 + " passed for userId " + userId);
9546 return mRecentTasks.getTaskDescriptionIcon(filePath);
9550 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9551 throws RemoteException {
9552 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9553 opts.getCustomInPlaceResId() == 0) {
9554 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9555 "with valid animation");
9557 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9558 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9559 opts.getCustomInPlaceResId());
9560 mWindowManager.executeAppTransition();
9563 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9564 boolean removeFromRecents) {
9565 if (removeFromRecents) {
9566 mRecentTasks.remove(tr);
9567 tr.removedFromRecents();
9569 ComponentName component = tr.getBaseIntent().getComponent();
9570 if (component == null) {
9571 Slog.w(TAG, "No component for base intent of task: " + tr);
9575 // Find any running services associated with this app and stop if needed.
9576 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9582 // Determine if the process(es) for this task should be killed.
9583 final String pkg = component.getPackageName();
9584 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9585 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9586 for (int i = 0; i < pmap.size(); i++) {
9588 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9589 for (int j = 0; j < uids.size(); j++) {
9590 ProcessRecord proc = uids.valueAt(j);
9591 if (proc.userId != tr.userId) {
9592 // Don't kill process for a different user.
9595 if (proc == mHomeProcess) {
9596 // Don't kill the home process along with tasks from the same package.
9599 if (!proc.pkgList.containsKey(pkg)) {
9600 // Don't kill process that is not associated with this task.
9604 for (int k = 0; k < proc.activities.size(); k++) {
9605 TaskRecord otherTask = proc.activities.get(k).task;
9606 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9607 // Don't kill process(es) that has an activity in a different task that is
9613 if (proc.foregroundServices) {
9614 // Don't kill process(es) with foreground service.
9618 // Add process to kill list.
9619 procsToKill.add(proc);
9623 // Kill the running processes.
9624 for (int i = 0; i < procsToKill.size(); i++) {
9625 ProcessRecord pr = procsToKill.get(i);
9626 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9627 && pr.curReceiver == null) {
9628 pr.kill("remove task", true);
9630 // We delay killing processes that are not in the background or running a receiver.
9631 pr.waitingToKill = "remove task";
9636 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9637 // Remove all tasks with activities in the specified package from the list of recent tasks
9638 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9639 TaskRecord tr = mRecentTasks.get(i);
9640 if (tr.userId != userId) continue;
9642 ComponentName cn = tr.intent.getComponent();
9643 if (cn != null && cn.getPackageName().equals(packageName)) {
9644 // If the package name matches, remove the task.
9645 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9650 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9653 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9654 TaskRecord tr = mRecentTasks.get(i);
9655 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9659 ComponentName cn = tr.intent.getComponent();
9660 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9661 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9662 if (sameComponent) {
9663 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9669 * Removes the task with the specified task id.
9671 * @param taskId Identifier of the task to be removed.
9672 * @param killProcess Kill any process associated with the task if possible.
9673 * @param removeFromRecents Whether to also remove the task from recents.
9674 * @return Returns true if the given task was found and removed.
9676 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9677 boolean removeFromRecents) {
9678 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9679 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9681 tr.removeTaskActivitiesLocked();
9682 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9683 if (tr.isPersistable) {
9684 notifyTaskPersisterLocked(null, true);
9688 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9693 public void removeStack(int stackId) {
9694 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9695 if (stackId == HOME_STACK_ID) {
9696 throw new IllegalArgumentException("Removing home stack is not allowed.");
9699 synchronized (this) {
9700 final long ident = Binder.clearCallingIdentity();
9702 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9703 if (stack == null) {
9706 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9707 for (int i = tasks.size() - 1; i >= 0; i--) {
9708 removeTaskByIdLocked(
9709 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9712 Binder.restoreCallingIdentity(ident);
9718 public boolean removeTask(int taskId) {
9719 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9720 synchronized (this) {
9721 final long ident = Binder.clearCallingIdentity();
9723 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9725 Binder.restoreCallingIdentity(ident);
9731 * TODO: Add mController hook
9734 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9735 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9737 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9738 synchronized(this) {
9739 moveTaskToFrontLocked(taskId, flags, bOptions);
9743 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9744 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9746 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9747 Binder.getCallingUid(), -1, -1, "Task to front")) {
9748 ActivityOptions.abort(options);
9751 final long origId = Binder.clearCallingIdentity();
9753 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9755 Slog.d(TAG, "Could not find task for id: "+ taskId);
9758 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9759 mStackSupervisor.showLockTaskToast();
9760 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9763 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9764 if (prev != null && prev.isRecentsActivity()) {
9765 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9767 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9768 false /* forceNonResizable */);
9770 Binder.restoreCallingIdentity(origId);
9772 ActivityOptions.abort(options);
9776 * Moves an activity, and all of the other activities within the same task, to the bottom
9777 * of the history stack. The activity's order within the task is unchanged.
9779 * @param token A reference to the activity we wish to move
9780 * @param nonRoot If false then this only works if the activity is the root
9781 * of a task; if true it will work for any activity in a task.
9782 * @return Returns true if the move completed, false if not.
9785 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9786 enforceNotIsolatedCaller("moveActivityTaskToBack");
9787 synchronized(this) {
9788 final long origId = Binder.clearCallingIdentity();
9790 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9791 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9793 if (mStackSupervisor.isLockedTask(task)) {
9794 mStackSupervisor.showLockTaskToast();
9797 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9800 Binder.restoreCallingIdentity(origId);
9807 public void moveTaskBackwards(int task) {
9808 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9809 "moveTaskBackwards()");
9811 synchronized(this) {
9812 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9813 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9816 final long origId = Binder.clearCallingIdentity();
9817 moveTaskBackwardsLocked(task);
9818 Binder.restoreCallingIdentity(origId);
9822 private final void moveTaskBackwardsLocked(int task) {
9823 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9827 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9828 IActivityContainerCallback callback) throws RemoteException {
9829 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9830 synchronized (this) {
9831 if (parentActivityToken == null) {
9832 throw new IllegalArgumentException("parent token must not be null");
9834 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9838 if (callback == null) {
9839 throw new IllegalArgumentException("callback must not be null");
9841 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9846 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9847 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9848 synchronized (this) {
9849 mStackSupervisor.deleteActivityContainer(container);
9854 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9855 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9856 synchronized (this) {
9857 final int stackId = mStackSupervisor.getNextStackId();
9858 final ActivityStack stack =
9859 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9860 if (stack == null) {
9863 return stack.mActivityContainer;
9868 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9869 synchronized (this) {
9870 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9871 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9872 return stack.mActivityContainer.getDisplayId();
9874 return Display.DEFAULT_DISPLAY;
9879 public int getActivityStackId(IBinder token) throws RemoteException {
9880 synchronized (this) {
9881 ActivityStack stack = ActivityRecord.getStackLocked(token);
9882 if (stack == null) {
9883 return INVALID_STACK_ID;
9885 return stack.mStackId;
9890 public void exitFreeformMode(IBinder token) throws RemoteException {
9891 synchronized (this) {
9892 long ident = Binder.clearCallingIdentity();
9894 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9896 throw new IllegalArgumentException(
9897 "exitFreeformMode: No activity record matching token=" + token);
9899 final ActivityStack stack = r.getStackLocked(token);
9900 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9901 throw new IllegalStateException(
9902 "exitFreeformMode: You can only go fullscreen from freeform.");
9904 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9905 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9906 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9908 Binder.restoreCallingIdentity(ident);
9914 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9915 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9916 if (stackId == HOME_STACK_ID) {
9917 throw new IllegalArgumentException(
9918 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9920 synchronized (this) {
9921 long ident = Binder.clearCallingIdentity();
9923 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9924 + " to stackId=" + stackId + " toTop=" + toTop);
9925 if (stackId == DOCKED_STACK_ID) {
9926 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9927 null /* initialBounds */);
9929 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9930 !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9931 if (result && stackId == DOCKED_STACK_ID) {
9932 // If task moved to docked stack - show recents if needed.
9933 mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9934 "moveTaskToDockedStack");
9937 Binder.restoreCallingIdentity(ident);
9943 public void swapDockedAndFullscreenStack() throws RemoteException {
9944 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9945 synchronized (this) {
9946 long ident = Binder.clearCallingIdentity();
9948 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9949 FULLSCREEN_WORKSPACE_STACK_ID);
9950 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9952 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9953 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9955 if (topTask == null || tasks == null || tasks.size() == 0) {
9957 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9961 // TODO: App transition
9962 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9964 // Defer the resume so resume/pausing while moving stacks is dangerous.
9965 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9966 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9967 ANIMATE, true /* deferResume */);
9968 final int size = tasks.size();
9969 for (int i = 0; i < size; i++) {
9970 final int id = tasks.get(i).taskId;
9971 if (id == topTask.taskId) {
9974 mStackSupervisor.moveTaskToStackLocked(id,
9975 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9976 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9979 // Because we deferred the resume, to avoid conflicts with stack switches while
9980 // resuming, we need to do it after all the tasks are moved.
9981 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9982 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9984 mWindowManager.executeAppTransition();
9986 Binder.restoreCallingIdentity(ident);
9992 * Moves the input task to the docked stack.
9994 * @param taskId Id of task to move.
9995 * @param createMode The mode the docked stack should be created in if it doesn't exist
9997 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9999 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10000 * @param toTop If the task and stack should be moved to the top.
10001 * @param animate Whether we should play an animation for the moving the task
10002 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10003 * docked stack. Pass {@code null} to use default bounds.
10006 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10007 Rect initialBounds, boolean moveHomeStackFront) {
10008 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10009 synchronized (this) {
10010 long ident = Binder.clearCallingIdentity();
10012 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10013 + " to createMode=" + createMode + " toTop=" + toTop);
10014 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10015 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10016 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10017 animate, DEFER_RESUME);
10019 if (moveHomeStackFront) {
10020 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10022 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10026 Binder.restoreCallingIdentity(ident);
10032 * Moves the top activity in the input stackId to the pinned stack.
10034 * @param stackId Id of stack to move the top activity to pinned stack.
10035 * @param bounds Bounds to use for pinned stack.
10037 * @return True if the top activity of the input stack was successfully moved to the pinned
10041 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10042 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10043 synchronized (this) {
10044 if (!mSupportsPictureInPicture) {
10045 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10046 + "Device doesn't support picture-in-pciture mode");
10049 long ident = Binder.clearCallingIdentity();
10051 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10053 Binder.restoreCallingIdentity(ident);
10059 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10060 boolean preserveWindows, boolean animate, int animationDuration) {
10061 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10062 long ident = Binder.clearCallingIdentity();
10064 synchronized (this) {
10066 if (stackId == PINNED_STACK_ID) {
10067 mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10069 throw new IllegalArgumentException("Stack: " + stackId
10070 + " doesn't support animated resize.");
10073 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10074 null /* tempTaskInsetBounds */, preserveWindows,
10075 allowResizeInDockedMode, !DEFER_RESUME);
10079 Binder.restoreCallingIdentity(ident);
10084 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10085 Rect tempDockedTaskInsetBounds,
10086 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10087 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10088 "resizeDockedStack()");
10089 long ident = Binder.clearCallingIdentity();
10091 synchronized (this) {
10092 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10093 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10097 Binder.restoreCallingIdentity(ident);
10102 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10103 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10104 "resizePinnedStack()");
10105 final long ident = Binder.clearCallingIdentity();
10107 synchronized (this) {
10108 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10111 Binder.restoreCallingIdentity(ident);
10116 public void positionTaskInStack(int taskId, int stackId, int position) {
10117 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10118 if (stackId == HOME_STACK_ID) {
10119 throw new IllegalArgumentException(
10120 "positionTaskInStack: Attempt to change the position of task "
10121 + taskId + " in/to home stack");
10123 synchronized (this) {
10124 long ident = Binder.clearCallingIdentity();
10126 if (DEBUG_STACK) Slog.d(TAG_STACK,
10127 "positionTaskInStack: positioning task=" + taskId
10128 + " in stackId=" + stackId + " at position=" + position);
10129 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10131 Binder.restoreCallingIdentity(ident);
10137 public List<StackInfo> getAllStackInfos() {
10138 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10139 long ident = Binder.clearCallingIdentity();
10141 synchronized (this) {
10142 return mStackSupervisor.getAllStackInfosLocked();
10145 Binder.restoreCallingIdentity(ident);
10150 public StackInfo getStackInfo(int stackId) {
10151 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10152 long ident = Binder.clearCallingIdentity();
10154 synchronized (this) {
10155 return mStackSupervisor.getStackInfoLocked(stackId);
10158 Binder.restoreCallingIdentity(ident);
10163 public boolean isInHomeStack(int taskId) {
10164 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10165 long ident = Binder.clearCallingIdentity();
10167 synchronized (this) {
10168 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10169 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10170 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10173 Binder.restoreCallingIdentity(ident);
10178 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10179 synchronized(this) {
10180 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10185 public void updateDeviceOwner(String packageName) {
10186 final int callingUid = Binder.getCallingUid();
10187 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10188 throw new SecurityException("updateDeviceOwner called from non-system process");
10190 synchronized (this) {
10191 mDeviceOwnerName = packageName;
10196 public void updateLockTaskPackages(int userId, String[] packages) {
10197 final int callingUid = Binder.getCallingUid();
10198 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10199 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10200 "updateLockTaskPackages()");
10202 synchronized (this) {
10203 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10204 Arrays.toString(packages));
10205 mLockTaskPackages.put(userId, packages);
10206 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10211 void startLockTaskModeLocked(TaskRecord task) {
10212 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10213 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10217 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10218 // is initiated by system after the pinning request was shown and locked mode is initiated
10219 // by an authorized app directly
10220 final int callingUid = Binder.getCallingUid();
10221 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10222 long ident = Binder.clearCallingIdentity();
10224 if (!isSystemInitiated) {
10225 task.mLockTaskUid = callingUid;
10226 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10227 // startLockTask() called by app and task mode is lockTaskModeDefault.
10228 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10229 StatusBarManagerInternal statusBarManager =
10230 LocalServices.getService(StatusBarManagerInternal.class);
10231 if (statusBarManager != null) {
10232 statusBarManager.showScreenPinningRequest(task.taskId);
10237 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10238 if (stack == null || task != stack.topTask()) {
10239 throw new IllegalArgumentException("Invalid task, not in foreground");
10242 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10244 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10245 ActivityManager.LOCK_TASK_MODE_PINNED :
10246 ActivityManager.LOCK_TASK_MODE_LOCKED,
10247 "startLockTask", true);
10249 Binder.restoreCallingIdentity(ident);
10254 public void startLockTaskMode(int taskId) {
10255 synchronized (this) {
10256 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10257 if (task != null) {
10258 startLockTaskModeLocked(task);
10264 public void startLockTaskMode(IBinder token) {
10265 synchronized (this) {
10266 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10270 final TaskRecord task = r.task;
10271 if (task != null) {
10272 startLockTaskModeLocked(task);
10278 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10279 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10280 // This makes inner call to look as if it was initiated by system.
10281 long ident = Binder.clearCallingIdentity();
10283 synchronized (this) {
10284 startLockTaskMode(taskId);
10287 Binder.restoreCallingIdentity(ident);
10292 public void stopLockTaskMode() {
10293 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10294 if (lockTask == null) {
10295 // Our work here is done.
10299 final int callingUid = Binder.getCallingUid();
10300 final int lockTaskUid = lockTask.mLockTaskUid;
10301 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10302 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10306 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10307 // It is possible lockTaskMode was started by the system process because
10308 // android:lockTaskMode is set to a locking value in the application manifest
10309 // instead of the app calling startLockTaskMode. In this case
10310 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10311 // {@link TaskRecord.effectiveUid} instead. Also caller with
10312 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10313 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10314 && callingUid != lockTaskUid
10315 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10316 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10317 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10320 long ident = Binder.clearCallingIdentity();
10322 Log.d(TAG, "stopLockTaskMode");
10324 synchronized (this) {
10325 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10326 "stopLockTask", true);
10328 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10330 tm.showInCallScreen(false);
10333 Binder.restoreCallingIdentity(ident);
10338 * This API should be called by SystemUI only when user perform certain action to dismiss
10339 * lock task mode. We should only dismiss pinned lock task mode in this case.
10342 public void stopSystemLockTaskMode() throws RemoteException {
10343 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10344 stopLockTaskMode();
10346 mStackSupervisor.showLockTaskToast();
10351 public boolean isInLockTaskMode() {
10352 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10356 public int getLockTaskModeState() {
10357 synchronized (this) {
10358 return mStackSupervisor.getLockTaskModeState();
10363 public void showLockTaskEscapeMessage(IBinder token) {
10364 synchronized (this) {
10365 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10369 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10373 // =========================================================
10374 // CONTENT PROVIDERS
10375 // =========================================================
10377 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10378 List<ProviderInfo> providers = null;
10380 providers = AppGlobals.getPackageManager()
10381 .queryContentProviders(app.processName, app.uid,
10382 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10383 | MATCH_DEBUG_TRIAGED_MISSING)
10385 } catch (RemoteException ex) {
10387 if (DEBUG_MU) Slog.v(TAG_MU,
10388 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10389 int userId = app.userId;
10390 if (providers != null) {
10391 int N = providers.size();
10392 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10393 for (int i=0; i<N; i++) {
10394 // TODO: keep logic in sync with installEncryptionUnawareProviders
10396 (ProviderInfo)providers.get(i);
10397 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10398 cpi.name, cpi.flags);
10399 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10400 // This is a singleton provider, but a user besides the
10401 // default user is asking to initialize a process it runs
10402 // in... well, no, it doesn't actually run in this process,
10403 // it runs in the process of the default user. Get rid of it.
10404 providers.remove(i);
10410 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10411 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10413 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10414 mProviderMap.putProviderByClass(comp, cpr);
10416 if (DEBUG_MU) Slog.v(TAG_MU,
10417 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10418 app.pubProviders.put(cpi.name, cpr);
10419 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10420 // Don't add this if it is a platform component that is marked
10421 // to run in multiple processes, because this is actually
10422 // part of the framework so doesn't make sense to track as a
10423 // separate apk in the process.
10424 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10427 notifyPackageUse(cpi.applicationInfo.packageName,
10428 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10435 * Check if the calling UID has a possible chance at accessing the provider
10436 * at the given authority and user.
10438 public String checkContentProviderAccess(String authority, int userId) {
10439 if (userId == UserHandle.USER_ALL) {
10440 mContext.enforceCallingOrSelfPermission(
10441 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10442 userId = UserHandle.getCallingUserId();
10445 ProviderInfo cpi = null;
10447 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10448 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10449 | PackageManager.MATCH_DIRECT_BOOT_AWARE
10450 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10452 } catch (RemoteException ignored) {
10455 // TODO: make this an outright failure in a future platform release;
10456 // until then anonymous content notifications are unprotected
10457 //return "Failed to find provider " + authority + " for user " + userId;
10461 ProcessRecord r = null;
10462 synchronized (mPidsSelfLocked) {
10463 r = mPidsSelfLocked.get(Binder.getCallingPid());
10466 return "Failed to find PID " + Binder.getCallingPid();
10469 synchronized (this) {
10470 return checkContentProviderPermissionLocked(cpi, r, userId, true);
10475 * Check if {@link ProcessRecord} has a possible chance at accessing the
10476 * given {@link ProviderInfo}. Final permission checking is always done
10477 * in {@link ContentProvider}.
10479 private final String checkContentProviderPermissionLocked(
10480 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10481 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10482 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10483 boolean checkedGrants = false;
10485 // Looking for cross-user grants before enforcing the typical cross-users permissions
10486 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10487 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10488 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10491 checkedGrants = true;
10493 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10494 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10495 if (userId != tmpTargetUserId) {
10496 // When we actually went to determine the final targer user ID, this ended
10497 // up different than our initial check for the authority. This is because
10498 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10499 // SELF. So we need to re-check the grants again.
10500 checkedGrants = false;
10503 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10504 cpi.applicationInfo.uid, cpi.exported)
10505 == PackageManager.PERMISSION_GRANTED) {
10508 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10509 cpi.applicationInfo.uid, cpi.exported)
10510 == PackageManager.PERMISSION_GRANTED) {
10514 PathPermission[] pps = cpi.pathPermissions;
10516 int i = pps.length;
10519 PathPermission pp = pps[i];
10520 String pprperm = pp.getReadPermission();
10521 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10522 cpi.applicationInfo.uid, cpi.exported)
10523 == PackageManager.PERMISSION_GRANTED) {
10526 String ppwperm = pp.getWritePermission();
10527 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10528 cpi.applicationInfo.uid, cpi.exported)
10529 == PackageManager.PERMISSION_GRANTED) {
10534 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10539 if (!cpi.exported) {
10540 msg = "Permission Denial: opening provider " + cpi.name
10541 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10542 + ", uid=" + callingUid + ") that is not exported from uid "
10543 + cpi.applicationInfo.uid;
10545 msg = "Permission Denial: opening provider " + cpi.name
10546 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10547 + ", uid=" + callingUid + ") requires "
10548 + cpi.readPermission + " or " + cpi.writePermission;
10555 * Returns if the ContentProvider has granted a uri to callingUid
10557 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10558 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10559 if (perms != null) {
10560 for (int i=perms.size()-1; i>=0; i--) {
10561 GrantUri grantUri = perms.keyAt(i);
10562 if (grantUri.sourceUserId == userId || !checkUser) {
10563 if (matchesProvider(grantUri.uri, cpi)) {
10573 * Returns true if the uri authority is one of the authorities specified in the provider.
10575 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10576 String uriAuth = uri.getAuthority();
10577 String cpiAuth = cpi.authority;
10578 if (cpiAuth.indexOf(';') == -1) {
10579 return cpiAuth.equals(uriAuth);
10581 String[] cpiAuths = cpiAuth.split(";");
10582 int length = cpiAuths.length;
10583 for (int i = 0; i < length; i++) {
10584 if (cpiAuths[i].equals(uriAuth)) return true;
10589 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10590 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10592 for (int i=0; i<r.conProviders.size(); i++) {
10593 ContentProviderConnection conn = r.conProviders.get(i);
10594 if (conn.provider == cpr) {
10595 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10596 "Adding provider requested by "
10597 + r.processName + " from process "
10598 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10599 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10601 conn.stableCount++;
10602 conn.numStableIncs++;
10604 conn.unstableCount++;
10605 conn.numUnstableIncs++;
10610 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10612 conn.stableCount = 1;
10613 conn.numStableIncs = 1;
10615 conn.unstableCount = 1;
10616 conn.numUnstableIncs = 1;
10618 cpr.connections.add(conn);
10619 r.conProviders.add(conn);
10620 startAssociationLocked(r.uid, r.processName, r.curProcState,
10621 cpr.uid, cpr.name, cpr.info.processName);
10624 cpr.addExternalProcessHandleLocked(externalProcessToken);
10628 boolean decProviderCountLocked(ContentProviderConnection conn,
10629 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10630 if (conn != null) {
10631 cpr = conn.provider;
10632 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10633 "Removing provider requested by "
10634 + conn.client.processName + " from process "
10635 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10636 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10638 conn.stableCount--;
10640 conn.unstableCount--;
10642 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10643 cpr.connections.remove(conn);
10644 conn.client.conProviders.remove(conn);
10645 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10646 // The client is more important than last activity -- note the time this
10647 // is happening, so we keep the old provider process around a bit as last
10648 // activity to avoid thrashing it.
10649 if (cpr.proc != null) {
10650 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10653 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10658 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10662 private void checkTime(long startTime, String where) {
10663 long now = SystemClock.uptimeMillis();
10664 if ((now-startTime) > 50) {
10665 // If we are taking more than 50ms, log about it.
10666 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10670 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10672 PROC_SPACE_TERM|PROC_PARENS,
10673 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
10676 private final long[] mProcessStateStatsLongs = new long[1];
10678 boolean isProcessAliveLocked(ProcessRecord proc) {
10679 if (proc.procStatFile == null) {
10680 proc.procStatFile = "/proc/" + proc.pid + "/stat";
10682 mProcessStateStatsLongs[0] = 0;
10683 if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10684 mProcessStateStatsLongs, null)) {
10685 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10688 final long state = mProcessStateStatsLongs[0];
10689 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10691 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10694 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10695 String name, IBinder token, boolean stable, int userId) {
10696 ContentProviderRecord cpr;
10697 ContentProviderConnection conn = null;
10698 ProviderInfo cpi = null;
10700 synchronized(this) {
10701 long startTime = SystemClock.uptimeMillis();
10703 ProcessRecord r = null;
10704 if (caller != null) {
10705 r = getRecordForAppLocked(caller);
10707 throw new SecurityException(
10708 "Unable to find app for caller " + caller
10709 + " (pid=" + Binder.getCallingPid()
10710 + ") when getting content provider " + name);
10714 boolean checkCrossUser = true;
10716 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10718 // First check if this content provider has been published...
10719 cpr = mProviderMap.getProviderByName(name, userId);
10720 // If that didn't work, check if it exists for user 0 and then
10721 // verify that it's a singleton provider before using it.
10722 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10723 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10726 if (isSingleton(cpi.processName, cpi.applicationInfo,
10727 cpi.name, cpi.flags)
10728 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10729 userId = UserHandle.USER_SYSTEM;
10730 checkCrossUser = false;
10738 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10739 if (providerRunning) {
10742 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10743 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10745 throw new SecurityException(msg);
10747 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10749 if (r != null && cpr.canRunHere(r)) {
10750 // This provider has been published or is in the process
10751 // of being published... but it is also allowed to run
10752 // in the caller's process, so don't make a connection
10753 // and just let the caller instantiate its own instance.
10754 ContentProviderHolder holder = cpr.newHolder(null);
10755 // don't give caller the provider object, it needs
10756 // to make its own.
10757 holder.provider = null;
10761 final long origId = Binder.clearCallingIdentity();
10763 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10765 // In this case the provider instance already exists, so we can
10766 // return it right away.
10767 conn = incProviderCountLocked(r, cpr, token, stable);
10768 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10769 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10770 // If this is a perceptible app accessing the provider,
10771 // make sure to count it as being accessed and thus
10772 // back up on the LRU list. This is good because
10773 // content providers are often expensive to start.
10774 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10775 updateLruProcessLocked(cpr.proc, false, null);
10776 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10780 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10781 final int verifiedAdj = cpr.proc.verifiedAdj;
10782 boolean success = updateOomAdjLocked(cpr.proc);
10783 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10784 // if the process has been successfully adjusted. So to reduce races with
10785 // it, we will check whether the process still exists. Note that this doesn't
10786 // completely get rid of races with LMK killing the process, but should make
10787 // them much smaller.
10788 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10791 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10792 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10793 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10794 // NOTE: there is still a race here where a signal could be
10795 // pending on the process even though we managed to update its
10796 // adj level. Not sure what to do about this, but at least
10797 // the race is now smaller.
10799 // Uh oh... it looks like the provider's process
10800 // has been killed on us. We need to wait for a new
10801 // process to be started, and make sure its death
10802 // doesn't kill our process.
10803 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10804 + " is crashing; detaching " + r);
10805 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10806 checkTime(startTime, "getContentProviderImpl: before appDied");
10807 appDiedLocked(cpr.proc);
10808 checkTime(startTime, "getContentProviderImpl: after appDied");
10810 // This wasn't the last ref our process had on
10811 // the provider... we have now been killed, bail.
10814 providerRunning = false;
10817 cpr.proc.verifiedAdj = cpr.proc.setAdj;
10820 Binder.restoreCallingIdentity(origId);
10823 if (!providerRunning) {
10825 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10826 cpi = AppGlobals.getPackageManager().
10827 resolveContentProvider(name,
10828 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10829 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10830 } catch (RemoteException ex) {
10835 // If the provider is a singleton AND
10836 // (it's a call within the same user || the provider is a
10838 // Then allow connecting to the singleton provider
10839 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10840 cpi.name, cpi.flags)
10841 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10843 userId = UserHandle.USER_SYSTEM;
10845 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10846 checkTime(startTime, "getContentProviderImpl: got app info for user");
10849 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10850 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10852 throw new SecurityException(msg);
10854 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10856 if (!mProcessesReady
10857 && !cpi.processName.equals("system")) {
10858 // If this content provider does not run in the system
10859 // process, and the system is not yet ready to run other
10860 // processes, then fail fast instead of hanging.
10861 throw new IllegalArgumentException(
10862 "Attempt to launch content provider before system ready");
10865 // Make sure that the user who owns this provider is running. If not,
10866 // we don't want to allow it to run.
10867 if (!mUserController.isUserRunningLocked(userId, 0)) {
10868 Slog.w(TAG, "Unable to launch app "
10869 + cpi.applicationInfo.packageName + "/"
10870 + cpi.applicationInfo.uid + " for provider "
10871 + name + ": user " + userId + " is stopped");
10875 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10876 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10877 cpr = mProviderMap.getProviderByClass(comp, userId);
10878 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10879 final boolean firstClass = cpr == null;
10881 final long ident = Binder.clearCallingIdentity();
10883 // If permissions need a review before any of the app components can run,
10884 // we return no provider and launch a review activity if the calling app
10885 // is in the foreground.
10886 if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10887 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10893 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10894 ApplicationInfo ai =
10895 AppGlobals.getPackageManager().
10896 getApplicationInfo(
10897 cpi.applicationInfo.packageName,
10898 STOCK_PM_FLAGS, userId);
10899 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10901 Slog.w(TAG, "No package info for content provider "
10905 ai = getAppInfoForUser(ai, userId);
10906 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10907 } catch (RemoteException ex) {
10908 // pm is in same process, this will never happen.
10910 Binder.restoreCallingIdentity(ident);
10914 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10916 if (r != null && cpr.canRunHere(r)) {
10917 // If this is a multiprocess provider, then just return its
10918 // info and allow the caller to instantiate it. Only do
10919 // this if the provider is the same user as the caller's
10920 // process, or can run as root (so can be in any process).
10921 return cpr.newHolder(null);
10924 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10925 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10926 + cpr.info.name + " callers=" + Debug.getCallers(6));
10928 // This is single process, and our app is now connecting to it.
10929 // See if we are already in the process of launching this
10931 final int N = mLaunchingProviders.size();
10933 for (i = 0; i < N; i++) {
10934 if (mLaunchingProviders.get(i) == cpr) {
10939 // If the provider is not already being launched, then get it
10942 final long origId = Binder.clearCallingIdentity();
10945 // Content provider is now in use, its package can't be stopped.
10947 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10948 AppGlobals.getPackageManager().setPackageStoppedState(
10949 cpr.appInfo.packageName, false, userId);
10950 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10951 } catch (RemoteException e) {
10952 } catch (IllegalArgumentException e) {
10953 Slog.w(TAG, "Failed trying to unstop package "
10954 + cpr.appInfo.packageName + ": " + e);
10957 // Use existing process if already started
10958 checkTime(startTime, "getContentProviderImpl: looking for process record");
10959 ProcessRecord proc = getProcessRecordLocked(
10960 cpi.processName, cpr.appInfo.uid, false);
10961 if (proc != null && proc.thread != null && !proc.killed) {
10962 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10963 "Installing in existing process " + proc);
10964 if (!proc.pubProviders.containsKey(cpi.name)) {
10965 checkTime(startTime, "getContentProviderImpl: scheduling install");
10966 proc.pubProviders.put(cpi.name, cpr);
10968 proc.thread.scheduleInstallProvider(cpi);
10969 } catch (RemoteException e) {
10973 checkTime(startTime, "getContentProviderImpl: before start process");
10974 proc = startProcessLocked(cpi.processName,
10975 cpr.appInfo, false, 0, "content provider",
10976 new ComponentName(cpi.applicationInfo.packageName,
10977 cpi.name), false, false, false);
10978 checkTime(startTime, "getContentProviderImpl: after start process");
10979 if (proc == null) {
10980 Slog.w(TAG, "Unable to launch app "
10981 + cpi.applicationInfo.packageName + "/"
10982 + cpi.applicationInfo.uid + " for provider "
10983 + name + ": process is bad");
10987 cpr.launchingApp = proc;
10988 mLaunchingProviders.add(cpr);
10990 Binder.restoreCallingIdentity(origId);
10994 checkTime(startTime, "getContentProviderImpl: updating data structures");
10996 // Make sure the provider is published (the same provider class
10997 // may be published under multiple names).
10999 mProviderMap.putProviderByClass(comp, cpr);
11002 mProviderMap.putProviderByName(name, cpr);
11003 conn = incProviderCountLocked(r, cpr, token, stable);
11004 if (conn != null) {
11005 conn.waiting = true;
11008 checkTime(startTime, "getContentProviderImpl: done!");
11011 // Wait for the provider to be published...
11012 synchronized (cpr) {
11013 while (cpr.provider == null) {
11014 if (cpr.launchingApp == null) {
11015 Slog.w(TAG, "Unable to launch app "
11016 + cpi.applicationInfo.packageName + "/"
11017 + cpi.applicationInfo.uid + " for provider "
11018 + name + ": launching app became null");
11019 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11020 UserHandle.getUserId(cpi.applicationInfo.uid),
11021 cpi.applicationInfo.packageName,
11022 cpi.applicationInfo.uid, name);
11026 if (DEBUG_MU) Slog.v(TAG_MU,
11027 "Waiting to start provider " + cpr
11028 + " launchingApp=" + cpr.launchingApp);
11029 if (conn != null) {
11030 conn.waiting = true;
11033 } catch (InterruptedException ex) {
11035 if (conn != null) {
11036 conn.waiting = false;
11041 return cpr != null ? cpr.newHolder(conn) : null;
11044 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11045 ProcessRecord r, final int userId) {
11046 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11047 cpi.packageName, userId)) {
11049 final boolean callerForeground = r == null || r.setSchedGroup
11050 != ProcessList.SCHED_GROUP_BACKGROUND;
11052 // Show a permission review UI only for starting from a foreground app
11053 if (!callerForeground) {
11054 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11055 + cpi.packageName + " requires a permissions review");
11059 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11060 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11061 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11062 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11064 if (DEBUG_PERMISSIONS_REVIEW) {
11065 Slog.i(TAG, "u" + userId + " Launching permission review "
11066 + "for package " + cpi.packageName);
11069 final UserHandle userHandle = new UserHandle(userId);
11070 mHandler.post(new Runnable() {
11072 public void run() {
11073 mContext.startActivityAsUser(intent, userHandle);
11083 PackageManagerInternal getPackageManagerInternalLocked() {
11084 if (mPackageManagerInt == null) {
11085 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11087 return mPackageManagerInt;
11091 public final ContentProviderHolder getContentProvider(
11092 IApplicationThread caller, String name, int userId, boolean stable) {
11093 enforceNotIsolatedCaller("getContentProvider");
11094 if (caller == null) {
11095 String msg = "null IApplicationThread when getting content provider "
11098 throw new SecurityException(msg);
11100 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11101 // with cross-user grant.
11102 return getContentProviderImpl(caller, name, null, stable, userId);
11105 public ContentProviderHolder getContentProviderExternal(
11106 String name, int userId, IBinder token) {
11107 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11108 "Do not have permission in call getContentProviderExternal()");
11109 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11110 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11111 return getContentProviderExternalUnchecked(name, token, userId);
11114 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11115 IBinder token, int userId) {
11116 return getContentProviderImpl(null, name, token, true, userId);
11120 * Drop a content provider from a ProcessRecord's bookkeeping
11122 public void removeContentProvider(IBinder connection, boolean stable) {
11123 enforceNotIsolatedCaller("removeContentProvider");
11124 long ident = Binder.clearCallingIdentity();
11126 synchronized (this) {
11127 ContentProviderConnection conn;
11129 conn = (ContentProviderConnection)connection;
11130 } catch (ClassCastException e) {
11131 String msg ="removeContentProvider: " + connection
11132 + " not a ContentProviderConnection";
11134 throw new IllegalArgumentException(msg);
11136 if (conn == null) {
11137 throw new NullPointerException("connection is null");
11139 if (decProviderCountLocked(conn, null, null, stable)) {
11140 updateOomAdjLocked();
11144 Binder.restoreCallingIdentity(ident);
11148 public void removeContentProviderExternal(String name, IBinder token) {
11149 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11150 "Do not have permission in call removeContentProviderExternal()");
11151 int userId = UserHandle.getCallingUserId();
11152 long ident = Binder.clearCallingIdentity();
11154 removeContentProviderExternalUnchecked(name, token, userId);
11156 Binder.restoreCallingIdentity(ident);
11160 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11161 synchronized (this) {
11162 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11164 //remove from mProvidersByClass
11165 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11169 //update content provider record entry info
11170 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11171 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11172 if (localCpr.hasExternalProcessHandles()) {
11173 if (localCpr.removeExternalProcessHandleLocked(token)) {
11174 updateOomAdjLocked();
11176 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11177 + " with no external reference for token: "
11181 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11182 + " with no external references.");
11187 public final void publishContentProviders(IApplicationThread caller,
11188 List<ContentProviderHolder> providers) {
11189 if (providers == null) {
11193 enforceNotIsolatedCaller("publishContentProviders");
11194 synchronized (this) {
11195 final ProcessRecord r = getRecordForAppLocked(caller);
11196 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11198 throw new SecurityException(
11199 "Unable to find app for caller " + caller
11200 + " (pid=" + Binder.getCallingPid()
11201 + ") when publishing content providers");
11204 final long origId = Binder.clearCallingIdentity();
11206 final int N = providers.size();
11207 for (int i = 0; i < N; i++) {
11208 ContentProviderHolder src = providers.get(i);
11209 if (src == null || src.info == null || src.provider == null) {
11212 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11213 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11215 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11216 mProviderMap.putProviderByClass(comp, dst);
11217 String names[] = dst.info.authority.split(";");
11218 for (int j = 0; j < names.length; j++) {
11219 mProviderMap.putProviderByName(names[j], dst);
11222 int launchingCount = mLaunchingProviders.size();
11224 boolean wasInLaunchingProviders = false;
11225 for (j = 0; j < launchingCount; j++) {
11226 if (mLaunchingProviders.get(j) == dst) {
11227 mLaunchingProviders.remove(j);
11228 wasInLaunchingProviders = true;
11233 if (wasInLaunchingProviders) {
11234 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11236 synchronized (dst) {
11237 dst.provider = src.provider;
11241 updateOomAdjLocked(r);
11242 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11243 src.info.authority);
11247 Binder.restoreCallingIdentity(origId);
11251 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11252 ContentProviderConnection conn;
11254 conn = (ContentProviderConnection)connection;
11255 } catch (ClassCastException e) {
11256 String msg ="refContentProvider: " + connection
11257 + " not a ContentProviderConnection";
11259 throw new IllegalArgumentException(msg);
11261 if (conn == null) {
11262 throw new NullPointerException("connection is null");
11265 synchronized (this) {
11267 conn.numStableIncs += stable;
11269 stable = conn.stableCount + stable;
11271 throw new IllegalStateException("stableCount < 0: " + stable);
11274 if (unstable > 0) {
11275 conn.numUnstableIncs += unstable;
11277 unstable = conn.unstableCount + unstable;
11278 if (unstable < 0) {
11279 throw new IllegalStateException("unstableCount < 0: " + unstable);
11282 if ((stable+unstable) <= 0) {
11283 throw new IllegalStateException("ref counts can't go to zero here: stable="
11284 + stable + " unstable=" + unstable);
11286 conn.stableCount = stable;
11287 conn.unstableCount = unstable;
11292 public void unstableProviderDied(IBinder connection) {
11293 ContentProviderConnection conn;
11295 conn = (ContentProviderConnection)connection;
11296 } catch (ClassCastException e) {
11297 String msg ="refContentProvider: " + connection
11298 + " not a ContentProviderConnection";
11300 throw new IllegalArgumentException(msg);
11302 if (conn == null) {
11303 throw new NullPointerException("connection is null");
11306 // Safely retrieve the content provider associated with the connection.
11307 IContentProvider provider;
11308 synchronized (this) {
11309 provider = conn.provider.provider;
11312 if (provider == null) {
11313 // Um, yeah, we're way ahead of you.
11317 // Make sure the caller is being honest with us.
11318 if (provider.asBinder().pingBinder()) {
11319 // Er, no, still looks good to us.
11320 synchronized (this) {
11321 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11322 + " says " + conn + " died, but we don't agree");
11327 // Well look at that! It's dead!
11328 synchronized (this) {
11329 if (conn.provider.provider != provider) {
11330 // But something changed... good enough.
11334 ProcessRecord proc = conn.provider.proc;
11335 if (proc == null || proc.thread == null) {
11336 // Seems like the process is already cleaned up.
11340 // As far as we're concerned, this is just like receiving a
11341 // death notification... just a bit prematurely.
11342 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11343 + ") early provider death");
11344 final long ident = Binder.clearCallingIdentity();
11346 appDiedLocked(proc);
11348 Binder.restoreCallingIdentity(ident);
11354 public void appNotRespondingViaProvider(IBinder connection) {
11355 enforceCallingPermission(
11356 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11358 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11359 if (conn == null) {
11360 Slog.w(TAG, "ContentProviderConnection is null");
11364 final ProcessRecord host = conn.provider.proc;
11365 if (host == null) {
11366 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11370 mHandler.post(new Runnable() {
11372 public void run() {
11373 mAppErrors.appNotResponding(host, null, null, false,
11374 "ContentProvider not responding");
11379 public final void installSystemProviders() {
11380 List<ProviderInfo> providers;
11381 synchronized (this) {
11382 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11383 providers = generateApplicationProvidersLocked(app);
11384 if (providers != null) {
11385 for (int i=providers.size()-1; i>=0; i--) {
11386 ProviderInfo pi = (ProviderInfo)providers.get(i);
11387 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11388 Slog.w(TAG, "Not installing system proc provider " + pi.name
11389 + ": not system .apk");
11390 providers.remove(i);
11395 if (providers != null) {
11396 mSystemThread.installSystemProviders(providers);
11399 mCoreSettingsObserver = new CoreSettingsObserver(this);
11400 mFontScaleSettingObserver = new FontScaleSettingObserver();
11402 //mUsageStatsService.monitorPackages();
11405 private void startPersistentApps(int matchFlags) {
11406 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11408 synchronized (this) {
11410 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11411 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11412 for (ApplicationInfo app : apps) {
11413 if (!"android".equals(app.packageName)) {
11414 addAppLocked(app, false, null /* ABI override */);
11417 } catch (RemoteException ex) {
11423 * When a user is unlocked, we need to install encryption-unaware providers
11424 * belonging to any running apps.
11426 private void installEncryptionUnawareProviders(int userId) {
11427 // We're only interested in providers that are encryption unaware, and
11428 // we don't care about uninstalled apps, since there's no way they're
11429 // running at this point.
11430 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11432 synchronized (this) {
11433 final int NP = mProcessNames.getMap().size();
11434 for (int ip = 0; ip < NP; ip++) {
11435 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11436 final int NA = apps.size();
11437 for (int ia = 0; ia < NA; ia++) {
11438 final ProcessRecord app = apps.valueAt(ia);
11439 if (app.userId != userId || app.thread == null || app.unlocked) continue;
11441 final int NG = app.pkgList.size();
11442 for (int ig = 0; ig < NG; ig++) {
11444 final String pkgName = app.pkgList.keyAt(ig);
11445 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11446 .getPackageInfo(pkgName, matchFlags, userId);
11447 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11448 for (ProviderInfo pi : pkgInfo.providers) {
11449 // TODO: keep in sync with generateApplicationProvidersLocked
11450 final boolean processMatch = Objects.equals(pi.processName,
11451 app.processName) || pi.multiprocess;
11452 final boolean userMatch = isSingleton(pi.processName,
11453 pi.applicationInfo, pi.name, pi.flags)
11454 ? (app.userId == UserHandle.USER_SYSTEM) : true;
11455 if (processMatch && userMatch) {
11456 Log.v(TAG, "Installing " + pi);
11457 app.thread.scheduleInstallProvider(pi);
11459 Log.v(TAG, "Skipping " + pi);
11463 } catch (RemoteException ignored) {
11472 * Allows apps to retrieve the MIME type of a URI.
11473 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11474 * users, then it does not need permission to access the ContentProvider.
11475 * Either, it needs cross-user uri grants.
11477 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11479 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11480 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11482 public String getProviderMimeType(Uri uri, int userId) {
11483 enforceNotIsolatedCaller("getProviderMimeType");
11484 final String name = uri.getAuthority();
11485 int callingUid = Binder.getCallingUid();
11486 int callingPid = Binder.getCallingPid();
11488 boolean clearedIdentity = false;
11489 synchronized (this) {
11490 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11492 if (canClearIdentity(callingPid, callingUid, userId)) {
11493 clearedIdentity = true;
11494 ident = Binder.clearCallingIdentity();
11496 ContentProviderHolder holder = null;
11498 holder = getContentProviderExternalUnchecked(name, null, userId);
11499 if (holder != null) {
11500 return holder.provider.getType(uri);
11502 } catch (RemoteException e) {
11503 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11505 } catch (Exception e) {
11506 Log.w(TAG, "Exception while determining type of " + uri, e);
11509 // We need to clear the identity to call removeContentProviderExternalUnchecked
11510 if (!clearedIdentity) {
11511 ident = Binder.clearCallingIdentity();
11514 if (holder != null) {
11515 removeContentProviderExternalUnchecked(name, null, userId);
11518 Binder.restoreCallingIdentity(ident);
11525 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11526 if (UserHandle.getUserId(callingUid) == userId) {
11529 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11530 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11531 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11532 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11538 // =========================================================
11539 // GLOBAL MANAGEMENT
11540 // =========================================================
11542 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11543 boolean isolated, int isolatedUid) {
11544 String proc = customProcess != null ? customProcess : info.processName;
11545 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11546 final int userId = UserHandle.getUserId(info.uid);
11547 int uid = info.uid;
11549 if (isolatedUid == 0) {
11550 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11552 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11553 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11554 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11556 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11557 mNextIsolatedProcessUid++;
11558 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11559 // No process for this uid, use it.
11563 if (stepsLeft <= 0) {
11568 // Special case for startIsolatedProcess (internal only), where
11569 // the uid of the isolated process is specified by the caller.
11573 // Register the isolated UID with this application so BatteryStats knows to
11574 // attribute resource usage to the application.
11576 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11577 // about the process state of the isolated UID *before* it is registered with the
11578 // owning application.
11579 mBatteryStatsService.addIsolatedUid(uid, info.uid);
11581 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11582 if (!mBooted && !mBooting
11583 && userId == UserHandle.USER_SYSTEM
11584 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11585 r.persistent = true;
11587 addProcessNameLocked(r);
11591 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11592 String abiOverride) {
11595 app = getProcessRecordLocked(info.processName, info.uid, true);
11601 app = newProcessRecordLocked(info, null, isolated, 0);
11602 updateLruProcessLocked(app, false, null);
11603 updateOomAdjLocked();
11606 // This package really, really can not be stopped.
11608 AppGlobals.getPackageManager().setPackageStoppedState(
11609 info.packageName, false, UserHandle.getUserId(app.uid));
11610 } catch (RemoteException e) {
11611 } catch (IllegalArgumentException e) {
11612 Slog.w(TAG, "Failed trying to unstop package "
11613 + info.packageName + ": " + e);
11616 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11617 app.persistent = true;
11618 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11620 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11621 mPersistentStartingProcesses.add(app);
11622 startProcessLocked(app, "added application", app.processName, abiOverride,
11623 null /* entryPoint */, null /* entryPointArgs */);
11629 public void unhandledBack() {
11630 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11631 "unhandledBack()");
11633 synchronized(this) {
11634 final long origId = Binder.clearCallingIdentity();
11636 getFocusedStack().unhandledBackLocked();
11638 Binder.restoreCallingIdentity(origId);
11643 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11644 enforceNotIsolatedCaller("openContentUri");
11645 final int userId = UserHandle.getCallingUserId();
11646 String name = uri.getAuthority();
11647 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11648 ParcelFileDescriptor pfd = null;
11650 // We record the binder invoker's uid in thread-local storage before
11651 // going to the content provider to open the file. Later, in the code
11652 // that handles all permissions checks, we look for this uid and use
11653 // that rather than the Activity Manager's own uid. The effect is that
11654 // we do the check against the caller's permissions even though it looks
11655 // to the content provider like the Activity Manager itself is making
11657 Binder token = new Binder();
11658 sCallerIdentity.set(new Identity(
11659 token, Binder.getCallingPid(), Binder.getCallingUid()));
11661 pfd = cph.provider.openFile(null, uri, "r", null, token);
11662 } catch (FileNotFoundException e) {
11663 // do nothing; pfd will be returned null
11665 // Ensure that whatever happens, we clean up the identity state
11666 sCallerIdentity.remove();
11667 // Ensure we're done with the provider.
11668 removeContentProviderExternalUnchecked(name, null, userId);
11671 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11676 // Actually is sleeping or shutting down or whatever else in the future
11677 // is an inactive state.
11678 boolean isSleepingOrShuttingDownLocked() {
11679 return isSleepingLocked() || mShuttingDown;
11682 boolean isShuttingDownLocked() {
11683 return mShuttingDown;
11686 boolean isSleepingLocked() {
11690 void onWakefulnessChanged(int wakefulness) {
11691 synchronized(this) {
11692 mWakefulness = wakefulness;
11693 updateSleepIfNeededLocked();
11697 void finishRunningVoiceLocked() {
11698 if (mRunningVoice != null) {
11699 mRunningVoice = null;
11700 mVoiceWakeLock.release();
11701 updateSleepIfNeededLocked();
11705 void startTimeTrackingFocusedActivityLocked() {
11706 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11707 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11711 void updateSleepIfNeededLocked() {
11712 if (mSleeping && !shouldSleepLocked()) {
11714 startTimeTrackingFocusedActivityLocked();
11715 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11716 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11717 sendNotifyVrManagerOfSleepState(false);
11718 updateOomAdjLocked();
11719 } else if (!mSleeping && shouldSleepLocked()) {
11721 if (mCurAppTimeTracker != null) {
11722 mCurAppTimeTracker.stop();
11724 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11725 mStackSupervisor.goingToSleepLocked();
11726 sendNotifyVrManagerOfSleepState(true);
11727 updateOomAdjLocked();
11729 // Initialize the wake times of all processes.
11730 checkExcessivePowerUsageLocked(false);
11731 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11732 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11733 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11737 private boolean shouldSleepLocked() {
11738 // Resume applications while running a voice interactor.
11739 if (mRunningVoice != null) {
11743 // TODO: Transform the lock screen state into a sleep token instead.
11744 switch (mWakefulness) {
11745 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11746 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11747 case PowerManagerInternal.WAKEFULNESS_DOZING:
11748 // Pause applications whenever the lock screen is shown or any sleep
11749 // tokens have been acquired.
11750 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11751 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11753 // If we're asleep then pause applications unconditionally.
11758 /** Pokes the task persister. */
11759 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11760 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11763 /** Notifies all listeners when the task stack has changed. */
11764 void notifyTaskStackChangedLocked() {
11765 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11766 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11767 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11768 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11771 /** Notifies all listeners when an Activity is pinned. */
11772 void notifyActivityPinnedLocked() {
11773 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11774 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11778 * Notifies all listeners when an attempt was made to start an an activity that is already
11779 * running in the pinned stack and the activity was not actually started, but the task is
11780 * either brought to the front or a new Intent is delivered to it.
11782 void notifyPinnedActivityRestartAttemptLocked() {
11783 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11784 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11787 /** Notifies all listeners when the pinned stack animation ends. */
11789 public void notifyPinnedStackAnimationEnded() {
11790 synchronized (this) {
11791 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11792 mHandler.obtainMessage(
11793 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11798 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11799 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11803 public boolean shutdown(int timeout) {
11804 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11805 != PackageManager.PERMISSION_GRANTED) {
11806 throw new SecurityException("Requires permission "
11807 + android.Manifest.permission.SHUTDOWN);
11810 boolean timedout = false;
11812 synchronized(this) {
11813 mShuttingDown = true;
11814 updateEventDispatchingLocked();
11815 timedout = mStackSupervisor.shutdownLocked(timeout);
11818 mAppOpsService.shutdown();
11819 if (mUsageStatsService != null) {
11820 mUsageStatsService.prepareShutdown();
11822 mBatteryStatsService.shutdown();
11823 synchronized (this) {
11824 mProcessStats.shutdownLocked();
11825 notifyTaskPersisterLocked(null, true);
11831 public final void activitySlept(IBinder token) {
11832 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11834 final long origId = Binder.clearCallingIdentity();
11836 synchronized (this) {
11837 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11839 mStackSupervisor.activitySleptLocked(r);
11843 Binder.restoreCallingIdentity(origId);
11846 private String lockScreenShownToString() {
11847 switch (mLockScreenShown) {
11848 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11849 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11850 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11851 default: return "Unknown=" + mLockScreenShown;
11855 void logLockScreen(String msg) {
11856 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11857 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11858 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11859 + " mSleeping=" + mSleeping);
11862 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11863 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11864 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11865 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11866 boolean wasRunningVoice = mRunningVoice != null;
11867 mRunningVoice = session;
11868 if (!wasRunningVoice) {
11869 mVoiceWakeLock.acquire();
11870 updateSleepIfNeededLocked();
11875 private void updateEventDispatchingLocked() {
11876 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11879 public void setLockScreenShown(boolean showing, boolean occluded) {
11880 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11881 != PackageManager.PERMISSION_GRANTED) {
11882 throw new SecurityException("Requires permission "
11883 + android.Manifest.permission.DEVICE_POWER);
11886 synchronized(this) {
11887 long ident = Binder.clearCallingIdentity();
11889 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11890 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11891 if (showing && occluded) {
11892 // The lock screen is currently showing, but is occluded by a window that can
11893 // show on top of the lock screen. In this can we want to dismiss the docked
11894 // stack since it will be complicated/risky to try to put the activity on top
11895 // of the lock screen in the right fullscreen configuration.
11896 mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11897 mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11900 updateSleepIfNeededLocked();
11902 Binder.restoreCallingIdentity(ident);
11908 public void notifyLockedProfile(@UserIdInt int userId) {
11910 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11911 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11913 } catch (RemoteException ex) {
11914 throw new SecurityException("Fail to check is caller a privileged app", ex);
11917 synchronized (this) {
11918 if (mStackSupervisor.isUserLockedProfile(userId)) {
11919 final long ident = Binder.clearCallingIdentity();
11921 final int currentUserId = mUserController.getCurrentUserIdLocked();
11923 // Drop locked freeform tasks out into the fullscreen stack.
11924 // TODO: Redact the tasks in place. It's much better to keep them on the screen
11925 // where they were before, but in an obscured state.
11926 mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11928 if (mUserController.isLockScreenDisabled(currentUserId)) {
11929 // If there is no device lock, we will show the profile's credential page.
11930 mActivityStarter.showConfirmDeviceCredential(userId);
11932 // Showing launcher to avoid user entering credential twice.
11933 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11936 Binder.restoreCallingIdentity(ident);
11943 public void startConfirmDeviceCredentialIntent(Intent intent) {
11944 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11945 synchronized (this) {
11946 final long ident = Binder.clearCallingIdentity();
11948 mActivityStarter.startConfirmCredentialIntent(intent);
11950 Binder.restoreCallingIdentity(ident);
11956 public void stopAppSwitches() {
11957 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11958 != PackageManager.PERMISSION_GRANTED) {
11959 throw new SecurityException("viewquires permission "
11960 + android.Manifest.permission.STOP_APP_SWITCHES);
11963 synchronized(this) {
11964 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11965 + APP_SWITCH_DELAY_TIME;
11966 mDidAppSwitch = false;
11967 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11968 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11969 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11973 public void resumeAppSwitches() {
11974 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11975 != PackageManager.PERMISSION_GRANTED) {
11976 throw new SecurityException("Requires permission "
11977 + android.Manifest.permission.STOP_APP_SWITCHES);
11980 synchronized(this) {
11981 // Note that we don't execute any pending app switches... we will
11982 // let those wait until either the timeout, or the next start
11983 // activity request.
11984 mAppSwitchesAllowedTime = 0;
11988 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11989 int callingPid, int callingUid, String name) {
11990 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11994 int perm = checkComponentPermission(
11995 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11996 sourceUid, -1, true);
11997 if (perm == PackageManager.PERMISSION_GRANTED) {
12001 // If the actual IPC caller is different from the logical source, then
12002 // also see if they are allowed to control app switches.
12003 if (callingUid != -1 && callingUid != sourceUid) {
12004 perm = checkComponentPermission(
12005 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12006 callingUid, -1, true);
12007 if (perm == PackageManager.PERMISSION_GRANTED) {
12012 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12016 public void setDebugApp(String packageName, boolean waitForDebugger,
12017 boolean persistent) {
12018 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12021 long ident = Binder.clearCallingIdentity();
12023 // Note that this is not really thread safe if there are multiple
12024 // callers into it at the same time, but that's not a situation we
12027 final ContentResolver resolver = mContext.getContentResolver();
12028 Settings.Global.putString(
12029 resolver, Settings.Global.DEBUG_APP,
12031 Settings.Global.putInt(
12032 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12033 waitForDebugger ? 1 : 0);
12036 synchronized (this) {
12038 mOrigDebugApp = mDebugApp;
12039 mOrigWaitForDebugger = mWaitForDebugger;
12041 mDebugApp = packageName;
12042 mWaitForDebugger = waitForDebugger;
12043 mDebugTransient = !persistent;
12044 if (packageName != null) {
12045 forceStopPackageLocked(packageName, -1, false, false, true, true,
12046 false, UserHandle.USER_ALL, "set debug app");
12050 Binder.restoreCallingIdentity(ident);
12054 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12055 synchronized (this) {
12056 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12057 if (!isDebuggable) {
12058 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12059 throw new SecurityException("Process not debuggable: " + app.packageName);
12063 mTrackAllocationApp = processName;
12067 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12068 synchronized (this) {
12069 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12070 if (!isDebuggable) {
12071 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12072 throw new SecurityException("Process not debuggable: " + app.packageName);
12075 mProfileApp = processName;
12076 mProfileFile = profilerInfo.profileFile;
12077 if (mProfileFd != null) {
12079 mProfileFd.close();
12080 } catch (IOException e) {
12084 mProfileFd = profilerInfo.profileFd;
12085 mSamplingInterval = profilerInfo.samplingInterval;
12086 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12091 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12092 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12093 if (!isDebuggable) {
12094 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12095 throw new SecurityException("Process not debuggable: " + app.packageName);
12098 mNativeDebuggingApp = processName;
12102 public void setAlwaysFinish(boolean enabled) {
12103 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12104 "setAlwaysFinish()");
12106 long ident = Binder.clearCallingIdentity();
12108 Settings.Global.putInt(
12109 mContext.getContentResolver(),
12110 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12112 synchronized (this) {
12113 mAlwaysFinishActivities = enabled;
12116 Binder.restoreCallingIdentity(ident);
12121 public void setLenientBackgroundCheck(boolean enabled) {
12122 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12123 "setLenientBackgroundCheck()");
12125 long ident = Binder.clearCallingIdentity();
12127 Settings.Global.putInt(
12128 mContext.getContentResolver(),
12129 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12131 synchronized (this) {
12132 mLenientBackgroundCheck = enabled;
12135 Binder.restoreCallingIdentity(ident);
12140 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12141 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12142 "setActivityController()");
12143 synchronized (this) {
12144 mController = controller;
12145 mControllerIsAMonkey = imAMonkey;
12146 Watchdog.getInstance().setActivityController(controller);
12151 public void setUserIsMonkey(boolean userIsMonkey) {
12152 synchronized (this) {
12153 synchronized (mPidsSelfLocked) {
12154 final int callingPid = Binder.getCallingPid();
12155 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12156 if (precessRecord == null) {
12157 throw new SecurityException("Unknown process: " + callingPid);
12159 if (precessRecord.instrumentationUiAutomationConnection == null) {
12160 throw new SecurityException("Only an instrumentation process "
12161 + "with a UiAutomation can call setUserIsMonkey");
12164 mUserIsMonkey = userIsMonkey;
12169 public boolean isUserAMonkey() {
12170 synchronized (this) {
12171 // If there is a controller also implies the user is a monkey.
12172 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12176 public void requestBugReport(int bugreportType) {
12177 String service = null;
12178 switch (bugreportType) {
12179 case ActivityManager.BUGREPORT_OPTION_FULL:
12180 service = "bugreport";
12182 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12183 service = "bugreportplus";
12185 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12186 service = "bugreportremote";
12188 case ActivityManager.BUGREPORT_OPTION_WEAR:
12189 service = "bugreportwear";
12191 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12192 service = "bugreportelefony";
12195 if (service == null) {
12196 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12199 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12200 SystemProperties.set("ctl.start", service);
12203 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12204 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12207 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12208 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12209 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12211 return KEY_DISPATCHING_TIMEOUT;
12215 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12216 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12217 != PackageManager.PERMISSION_GRANTED) {
12218 throw new SecurityException("Requires permission "
12219 + android.Manifest.permission.FILTER_EVENTS);
12221 ProcessRecord proc;
12223 synchronized (this) {
12224 synchronized (mPidsSelfLocked) {
12225 proc = mPidsSelfLocked.get(pid);
12227 timeout = getInputDispatchingTimeoutLocked(proc);
12230 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12238 * Handle input dispatching timeouts.
12239 * Returns whether input dispatching should be aborted or not.
12241 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12242 final ActivityRecord activity, final ActivityRecord parent,
12243 final boolean aboveSystem, String reason) {
12244 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12245 != PackageManager.PERMISSION_GRANTED) {
12246 throw new SecurityException("Requires permission "
12247 + android.Manifest.permission.FILTER_EVENTS);
12250 final String annotation;
12251 if (reason == null) {
12252 annotation = "Input dispatching timed out";
12254 annotation = "Input dispatching timed out (" + reason + ")";
12257 if (proc != null) {
12258 synchronized (this) {
12259 if (proc.debugging) {
12264 // Give more time since we were dexopting.
12265 mDidDexOpt = false;
12269 if (proc.instrumentationClass != null) {
12270 Bundle info = new Bundle();
12271 info.putString("shortMsg", "keyDispatchingTimedOut");
12272 info.putString("longMsg", annotation);
12273 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12277 mHandler.post(new Runnable() {
12279 public void run() {
12280 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12289 public Bundle getAssistContextExtras(int requestType) {
12290 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12291 null, null, true /* focused */, true /* newSessionId */,
12292 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12296 synchronized (pae) {
12297 while (!pae.haveResult) {
12300 } catch (InterruptedException e) {
12304 synchronized (this) {
12305 buildAssistBundleLocked(pae, pae.result);
12306 mPendingAssistExtras.remove(pae);
12307 mUiHandler.removeCallbacks(pae);
12313 public boolean isAssistDataAllowedOnCurrentActivity() {
12315 synchronized (this) {
12316 userId = mUserController.getCurrentUserIdLocked();
12317 ActivityRecord activity = getFocusedStack().topActivity();
12318 if (activity == null) {
12321 userId = activity.userId;
12323 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12324 Context.DEVICE_POLICY_SERVICE);
12325 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12329 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12330 long ident = Binder.clearCallingIdentity();
12332 synchronized (this) {
12333 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12334 ActivityRecord top = getFocusedStack().topActivity();
12335 if (top != caller) {
12336 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12337 + " is not current top " + top);
12340 if (!top.nowVisible) {
12341 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12342 + " is not visible");
12346 AssistUtils utils = new AssistUtils(mContext);
12347 return utils.showSessionForActiveService(args,
12348 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12350 Binder.restoreCallingIdentity(ident);
12355 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12356 Bundle receiverExtras,
12357 IBinder activityToken, boolean focused, boolean newSessionId) {
12358 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12359 activityToken, focused, newSessionId,
12360 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12364 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12365 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12366 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12367 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12368 "enqueueAssistContext()");
12369 synchronized (this) {
12370 ActivityRecord activity = getFocusedStack().topActivity();
12371 if (activity == null) {
12372 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12375 if (activity.app == null || activity.app.thread == null) {
12376 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12380 if (activityToken != null) {
12381 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12382 if (activity != caller) {
12383 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12384 + " is not current top " + activity);
12389 activity = ActivityRecord.forTokenLocked(activityToken);
12390 if (activity == null) {
12391 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12392 + " couldn't be found");
12397 PendingAssistExtras pae;
12398 Bundle extras = new Bundle();
12399 if (args != null) {
12400 extras.putAll(args);
12402 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12403 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12404 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12406 // Increment the sessionId if necessary
12407 if (newSessionId) {
12411 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12412 requestType, mViSessionId);
12413 mPendingAssistExtras.add(pae);
12414 mUiHandler.postDelayed(pae, timeout);
12415 } catch (RemoteException e) {
12416 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12423 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12424 IResultReceiver receiver;
12425 synchronized (this) {
12426 mPendingAssistExtras.remove(pae);
12427 receiver = pae.receiver;
12429 if (receiver != null) {
12430 // Caller wants result sent back to them.
12431 Bundle sendBundle = new Bundle();
12432 // At least return the receiver extras
12433 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12434 pae.receiverExtras);
12436 pae.receiver.send(0, sendBundle);
12437 } catch (RemoteException e) {
12442 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12443 if (result != null) {
12444 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12446 if (pae.hint != null) {
12447 pae.extras.putBoolean(pae.hint, true);
12451 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12452 AssistContent content, Uri referrer) {
12453 PendingAssistExtras pae = (PendingAssistExtras)token;
12454 synchronized (pae) {
12455 pae.result = extras;
12456 pae.structure = structure;
12457 pae.content = content;
12458 if (referrer != null) {
12459 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12461 pae.haveResult = true;
12463 if (pae.intent == null && pae.receiver == null) {
12464 // Caller is just waiting for the result.
12469 // We are now ready to launch the assist activity.
12470 IResultReceiver sendReceiver = null;
12471 Bundle sendBundle = null;
12472 synchronized (this) {
12473 buildAssistBundleLocked(pae, extras);
12474 boolean exists = mPendingAssistExtras.remove(pae);
12475 mUiHandler.removeCallbacks(pae);
12480 if ((sendReceiver=pae.receiver) != null) {
12481 // Caller wants result sent back to them.
12482 sendBundle = new Bundle();
12483 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12484 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12485 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12486 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12487 pae.receiverExtras);
12490 if (sendReceiver != null) {
12492 sendReceiver.send(0, sendBundle);
12493 } catch (RemoteException e) {
12498 long ident = Binder.clearCallingIdentity();
12500 pae.intent.replaceExtras(pae.extras);
12501 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12502 | Intent.FLAG_ACTIVITY_SINGLE_TOP
12503 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12504 closeSystemDialogs("assist");
12506 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12507 } catch (ActivityNotFoundException e) {
12508 Slog.w(TAG, "No activity to handle assist action.", e);
12511 Binder.restoreCallingIdentity(ident);
12515 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12517 return enqueueAssistContext(requestType, intent, hint, null, null, null,
12518 true /* focused */, true /* newSessionId */,
12519 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12522 public void registerProcessObserver(IProcessObserver observer) {
12523 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12524 "registerProcessObserver()");
12525 synchronized (this) {
12526 mProcessObservers.register(observer);
12531 public void unregisterProcessObserver(IProcessObserver observer) {
12532 synchronized (this) {
12533 mProcessObservers.unregister(observer);
12538 public void registerUidObserver(IUidObserver observer, int which) {
12539 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12540 "registerUidObserver()");
12541 synchronized (this) {
12542 mUidObservers.register(observer, which);
12547 public void unregisterUidObserver(IUidObserver observer) {
12548 synchronized (this) {
12549 mUidObservers.unregister(observer);
12554 public boolean convertFromTranslucent(IBinder token) {
12555 final long origId = Binder.clearCallingIdentity();
12557 synchronized (this) {
12558 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12562 final boolean translucentChanged = r.changeWindowTranslucency(true);
12563 if (translucentChanged) {
12564 r.task.stack.releaseBackgroundResources(r);
12565 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12567 mWindowManager.setAppFullscreen(token, true);
12568 return translucentChanged;
12571 Binder.restoreCallingIdentity(origId);
12576 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12577 final long origId = Binder.clearCallingIdentity();
12579 synchronized (this) {
12580 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12584 int index = r.task.mActivities.lastIndexOf(r);
12586 ActivityRecord under = r.task.mActivities.get(index - 1);
12587 under.returningOptions = options;
12589 final boolean translucentChanged = r.changeWindowTranslucency(false);
12590 if (translucentChanged) {
12591 r.task.stack.convertActivityToTranslucent(r);
12593 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12594 mWindowManager.setAppFullscreen(token, false);
12595 return translucentChanged;
12598 Binder.restoreCallingIdentity(origId);
12603 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12604 final long origId = Binder.clearCallingIdentity();
12606 synchronized (this) {
12607 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12609 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12614 Binder.restoreCallingIdentity(origId);
12619 public boolean isBackgroundVisibleBehind(IBinder token) {
12620 final long origId = Binder.clearCallingIdentity();
12622 synchronized (this) {
12623 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12624 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12625 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12626 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12630 Binder.restoreCallingIdentity(origId);
12635 public ActivityOptions getActivityOptions(IBinder token) {
12636 final long origId = Binder.clearCallingIdentity();
12638 synchronized (this) {
12639 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12641 final ActivityOptions activityOptions = r.pendingOptions;
12642 r.pendingOptions = null;
12643 return activityOptions;
12648 Binder.restoreCallingIdentity(origId);
12653 public void setImmersive(IBinder token, boolean immersive) {
12654 synchronized(this) {
12655 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12657 throw new IllegalArgumentException();
12659 r.immersive = immersive;
12661 // update associated state if we're frontmost
12662 if (r == mFocusedActivity) {
12663 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12664 applyUpdateLockStateLocked(r);
12670 public boolean isImmersive(IBinder token) {
12671 synchronized (this) {
12672 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12674 throw new IllegalArgumentException();
12676 return r.immersive;
12680 public void setVrThread(int tid) {
12681 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12682 throw new UnsupportedOperationException("VR mode not supported on this device!");
12685 synchronized (this) {
12686 ProcessRecord proc;
12687 synchronized (mPidsSelfLocked) {
12688 final int pid = Binder.getCallingPid();
12689 proc = mPidsSelfLocked.get(pid);
12691 if (proc != null && mInVrMode && tid >= 0) {
12692 // ensure the tid belongs to the process
12693 if (!Process.isThreadInProcess(pid, tid)) {
12694 throw new IllegalArgumentException("VR thread does not belong to process");
12697 // reset existing VR thread to CFS if this thread still exists and belongs to
12698 // the calling process
12699 if (proc.vrThreadTid != 0
12700 && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12702 Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12703 } catch (IllegalArgumentException e) {
12704 // Ignore this. Only occurs in race condition where previous VR thread
12705 // was destroyed during this method call.
12709 proc.vrThreadTid = tid;
12711 // promote to FIFO now if the tid is non-zero
12713 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12714 proc.vrThreadTid > 0) {
12715 Process.setThreadScheduler(proc.vrThreadTid,
12716 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12718 } catch (IllegalArgumentException e) {
12719 Slog.e(TAG, "Failed to set scheduling policy, thread does"
12720 + " not exist:\n" + e);
12728 public void setRenderThread(int tid) {
12729 synchronized (this) {
12730 ProcessRecord proc;
12731 synchronized (mPidsSelfLocked) {
12732 int pid = Binder.getCallingPid();
12733 proc = mPidsSelfLocked.get(pid);
12734 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12735 // ensure the tid belongs to the process
12736 if (!Process.isThreadInProcess(pid, tid)) {
12737 throw new IllegalArgumentException(
12738 "Render thread does not belong to process");
12740 proc.renderThreadTid = tid;
12741 if (DEBUG_OOM_ADJ) {
12742 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12744 // promote to FIFO now
12745 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12746 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12747 if (mUseFifoUiScheduling) {
12748 Process.setThreadScheduler(proc.renderThreadTid,
12749 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12751 Process.setThreadPriority(proc.renderThreadTid, -10);
12755 if (DEBUG_OOM_ADJ) {
12756 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12757 "PID: " + pid + ", TID: " + tid + " FIFO: " +
12758 mUseFifoUiScheduling);
12766 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12767 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12768 throw new UnsupportedOperationException("VR mode not supported on this device!");
12771 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12774 synchronized (this) {
12775 r = ActivityRecord.isInStackLocked(token);
12779 throw new IllegalArgumentException();
12783 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12784 VrManagerInternal.NO_ERROR) {
12788 synchronized(this) {
12789 r.requestedVrComponent = (enabled) ? packageName : null;
12791 // Update associated state if this activity is currently focused
12792 if (r == mFocusedActivity) {
12793 applyUpdateVrModeLocked(r);
12800 public boolean isVrModePackageEnabled(ComponentName packageName) {
12801 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12802 throw new UnsupportedOperationException("VR mode not supported on this device!");
12805 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12807 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12808 VrManagerInternal.NO_ERROR;
12811 public boolean isTopActivityImmersive() {
12812 enforceNotIsolatedCaller("startActivity");
12813 synchronized (this) {
12814 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12815 return (r != null) ? r.immersive : false;
12820 public boolean isTopOfTask(IBinder token) {
12821 synchronized (this) {
12822 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12824 throw new IllegalArgumentException();
12826 return r.task.getTopActivity() == r;
12831 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12832 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12833 String msg = "Permission Denial: setHasTopUi() from pid="
12834 + Binder.getCallingPid()
12835 + ", uid=" + Binder.getCallingUid()
12836 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12838 throw new SecurityException(msg);
12840 final int pid = Binder.getCallingPid();
12841 final long origId = Binder.clearCallingIdentity();
12843 synchronized (this) {
12844 boolean changed = false;
12846 synchronized (mPidsSelfLocked) {
12847 pr = mPidsSelfLocked.get(pid);
12849 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12852 if (pr.hasTopUi != hasTopUi) {
12853 Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12854 pr.hasTopUi = hasTopUi;
12859 updateOomAdjLocked(pr);
12863 Binder.restoreCallingIdentity(origId);
12867 public final void enterSafeMode() {
12868 synchronized(this) {
12869 // It only makes sense to do this before the system is ready
12870 // and started launching other packages.
12871 if (!mSystemReady) {
12873 AppGlobals.getPackageManager().enterSafeMode();
12874 } catch (RemoteException e) {
12882 public final void showSafeModeOverlay() {
12883 View v = LayoutInflater.from(mContext).inflate(
12884 com.android.internal.R.layout.safe_mode, null);
12885 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12886 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12887 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12888 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12889 lp.gravity = Gravity.BOTTOM | Gravity.START;
12890 lp.format = v.getBackground().getOpacity();
12891 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12892 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12893 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12894 ((WindowManager)mContext.getSystemService(
12895 Context.WINDOW_SERVICE)).addView(v, lp);
12898 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12899 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12902 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12903 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12904 synchronized (stats) {
12905 if (mBatteryStatsService.isOnBattery()) {
12906 mBatteryStatsService.enforceCallingPermission();
12907 int MY_UID = Binder.getCallingUid();
12909 if (sender == null) {
12912 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12914 BatteryStatsImpl.Uid.Pkg pkg =
12915 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12916 sourcePkg != null ? sourcePkg : rec.key.packageName);
12917 pkg.noteWakeupAlarmLocked(tag);
12922 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12923 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12926 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12927 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12928 synchronized (stats) {
12929 mBatteryStatsService.enforceCallingPermission();
12930 int MY_UID = Binder.getCallingUid();
12932 if (sender == null) {
12935 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12937 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12941 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12942 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12945 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12946 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12947 synchronized (stats) {
12948 mBatteryStatsService.enforceCallingPermission();
12949 int MY_UID = Binder.getCallingUid();
12951 if (sender == null) {
12954 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12956 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12960 public boolean killPids(int[] pids, String pReason, boolean secure) {
12961 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12962 throw new SecurityException("killPids only available to the system");
12964 String reason = (pReason == null) ? "Unknown" : pReason;
12965 // XXX Note: don't acquire main activity lock here, because the window
12966 // manager calls in with its locks held.
12968 boolean killed = false;
12969 synchronized (mPidsSelfLocked) {
12971 for (int i=0; i<pids.length; i++) {
12972 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12973 if (proc != null) {
12974 int type = proc.setAdj;
12975 if (type > worstType) {
12981 // If the worst oom_adj is somewhere in the cached proc LRU range,
12982 // then constrain it so we will kill all cached procs.
12983 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12984 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12985 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12988 // If this is not a secure call, don't let it kill processes that
12990 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12991 worstType = ProcessList.SERVICE_ADJ;
12994 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12995 for (int i=0; i<pids.length; i++) {
12996 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12997 if (proc == null) {
13000 int adj = proc.setAdj;
13001 if (adj >= worstType && !proc.killedByAm) {
13002 proc.kill(reason, true);
13011 public void killUid(int appId, int userId, String reason) {
13012 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13013 synchronized (this) {
13014 final long identity = Binder.clearCallingIdentity();
13016 killPackageProcessesLocked(null, appId, userId,
13017 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13018 reason != null ? reason : "kill uid");
13020 Binder.restoreCallingIdentity(identity);
13026 public boolean killProcessesBelowForeground(String reason) {
13027 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13028 throw new SecurityException("killProcessesBelowForeground() only available to system");
13031 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13034 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13035 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13036 throw new SecurityException("killProcessesBelowAdj() only available to system");
13039 boolean killed = false;
13040 synchronized (mPidsSelfLocked) {
13041 final int size = mPidsSelfLocked.size();
13042 for (int i = 0; i < size; i++) {
13043 final int pid = mPidsSelfLocked.keyAt(i);
13044 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13045 if (proc == null) continue;
13047 final int adj = proc.setAdj;
13048 if (adj > belowAdj && !proc.killedByAm) {
13049 proc.kill(reason, true);
13058 public void hang(final IBinder who, boolean allowRestart) {
13059 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13060 != PackageManager.PERMISSION_GRANTED) {
13061 throw new SecurityException("Requires permission "
13062 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13065 final IBinder.DeathRecipient death = new DeathRecipient() {
13067 public void binderDied() {
13068 synchronized (this) {
13075 who.linkToDeath(death, 0);
13076 } catch (RemoteException e) {
13077 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13081 synchronized (this) {
13082 Watchdog.getInstance().setAllowRestart(allowRestart);
13083 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13084 synchronized (death) {
13085 while (who.isBinderAlive()) {
13088 } catch (InterruptedException e) {
13092 Watchdog.getInstance().setAllowRestart(true);
13097 public void restart() {
13098 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13099 != PackageManager.PERMISSION_GRANTED) {
13100 throw new SecurityException("Requires permission "
13101 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13104 Log.i(TAG, "Sending shutdown broadcast...");
13106 BroadcastReceiver br = new BroadcastReceiver() {
13107 @Override public void onReceive(Context context, Intent intent) {
13108 // Now the broadcast is done, finish up the low-level shutdown.
13109 Log.i(TAG, "Shutting down activity manager...");
13111 Log.i(TAG, "Shutdown complete, restarting!");
13112 Process.killProcess(Process.myPid());
13117 // First send the high-level shut down broadcast.
13118 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13119 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13120 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13121 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13122 mContext.sendOrderedBroadcastAsUser(intent,
13123 UserHandle.ALL, null, br, mHandler, 0, null, null);
13125 br.onReceive(mContext, intent);
13128 private long getLowRamTimeSinceIdle(long now) {
13129 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13133 public void performIdleMaintenance() {
13134 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13135 != PackageManager.PERMISSION_GRANTED) {
13136 throw new SecurityException("Requires permission "
13137 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13140 synchronized (this) {
13141 final long now = SystemClock.uptimeMillis();
13142 final long timeSinceLastIdle = now - mLastIdleTime;
13143 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13144 mLastIdleTime = now;
13145 mLowRamTimeSinceLastIdle = 0;
13146 if (mLowRamStartTime != 0) {
13147 mLowRamStartTime = now;
13150 StringBuilder sb = new StringBuilder(128);
13151 sb.append("Idle maintenance over ");
13152 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13153 sb.append(" low RAM for ");
13154 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13155 Slog.i(TAG, sb.toString());
13157 // If at least 1/3 of our time since the last idle period has been spent
13158 // with RAM low, then we want to kill processes.
13159 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13161 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13162 ProcessRecord proc = mLruProcesses.get(i);
13163 if (proc.notCachedSinceIdle) {
13164 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13165 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13166 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13167 if (doKilling && proc.initialIdlePss != 0
13168 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13169 sb = new StringBuilder(128);
13171 sb.append(proc.processName);
13172 sb.append(" in idle maint: pss=");
13173 sb.append(proc.lastPss);
13174 sb.append(", swapPss=");
13175 sb.append(proc.lastSwapPss);
13176 sb.append(", initialPss=");
13177 sb.append(proc.initialIdlePss);
13178 sb.append(", period=");
13179 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13180 sb.append(", lowRamPeriod=");
13181 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13182 Slog.wtfQuiet(TAG, sb.toString());
13183 proc.kill("idle maint (pss " + proc.lastPss
13184 + " from " + proc.initialIdlePss + ")", true);
13187 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13188 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13189 proc.notCachedSinceIdle = true;
13190 proc.initialIdlePss = 0;
13191 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13192 mTestPssMode, isSleepingLocked(), now);
13196 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13197 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13202 public void sendIdleJobTrigger() {
13203 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13204 != PackageManager.PERMISSION_GRANTED) {
13205 throw new SecurityException("Requires permission "
13206 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13209 final long ident = Binder.clearCallingIdentity();
13211 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13212 .setPackage("android")
13213 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13214 broadcastIntent(null, intent, null, null, 0, null, null, null,
13215 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13217 Binder.restoreCallingIdentity(ident);
13221 private void retrieveSettings() {
13222 final ContentResolver resolver = mContext.getContentResolver();
13223 final boolean freeformWindowManagement =
13224 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13225 || Settings.Global.getInt(
13226 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13227 final boolean supportsPictureInPicture =
13228 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13230 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13231 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13232 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13233 final boolean alwaysFinishActivities =
13234 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13235 final boolean lenientBackgroundCheck =
13236 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13237 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13238 final boolean forceResizable = Settings.Global.getInt(
13239 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13240 final boolean supportsLeanbackOnly =
13241 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13243 // Transfer any global setting for forcing RTL layout, into a System Property
13244 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13246 final Configuration configuration = new Configuration();
13247 Settings.System.getConfiguration(resolver, configuration);
13249 // This will take care of setting the correct layout direction flags
13250 configuration.setLayoutDirection(configuration.locale);
13253 synchronized (this) {
13254 mDebugApp = mOrigDebugApp = debugApp;
13255 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13256 mAlwaysFinishActivities = alwaysFinishActivities;
13257 mLenientBackgroundCheck = lenientBackgroundCheck;
13258 mSupportsLeanbackOnly = supportsLeanbackOnly;
13259 mForceResizableActivities = forceResizable;
13260 mWindowManager.setForceResizableTasks(mForceResizableActivities);
13261 if (supportsMultiWindow || forceResizable) {
13262 mSupportsMultiWindow = true;
13263 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13264 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13266 mSupportsMultiWindow = false;
13267 mSupportsFreeformWindowManagement = false;
13268 mSupportsPictureInPicture = false;
13270 // This happens before any activities are started, so we can
13271 // change mConfiguration in-place.
13272 updateConfigurationLocked(configuration, null, true);
13273 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13274 "Initial config: " + mConfiguration);
13276 // Load resources only after the current configuration has been set.
13277 final Resources res = mContext.getResources();
13278 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13279 mThumbnailWidth = res.getDimensionPixelSize(
13280 com.android.internal.R.dimen.thumbnail_width);
13281 mThumbnailHeight = res.getDimensionPixelSize(
13282 com.android.internal.R.dimen.thumbnail_height);
13283 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13284 com.android.internal.R.string.config_defaultPictureInPictureBounds));
13285 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13286 com.android.internal.R.string.config_appsNotReportingCrashes));
13287 if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13288 mFullscreenThumbnailScale = (float) res
13289 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13290 (float) mConfiguration.screenWidthDp;
13292 mFullscreenThumbnailScale = res.getFraction(
13293 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13298 public boolean testIsSystemReady() {
13299 // no need to synchronize(this) just to read & return the value
13300 return mSystemReady;
13303 public void systemReady(final Runnable goingCallback) {
13304 synchronized(this) {
13305 if (mSystemReady) {
13306 // If we're done calling all the receivers, run the next "boot phase" passed in
13307 // by the SystemServer
13308 if (goingCallback != null) {
13309 goingCallback.run();
13314 mLocalDeviceIdleController
13315 = LocalServices.getService(DeviceIdleController.LocalService.class);
13317 // Make sure we have the current profile info, since it is needed for security checks.
13318 mUserController.onSystemReady();
13319 mRecentTasks.onSystemReadyLocked();
13320 mAppOpsService.systemReady();
13321 mSystemReady = true;
13324 ArrayList<ProcessRecord> procsToKill = null;
13325 synchronized(mPidsSelfLocked) {
13326 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13327 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13328 if (!isAllowedWhileBooting(proc.info)){
13329 if (procsToKill == null) {
13330 procsToKill = new ArrayList<ProcessRecord>();
13332 procsToKill.add(proc);
13337 synchronized(this) {
13338 if (procsToKill != null) {
13339 for (int i=procsToKill.size()-1; i>=0; i--) {
13340 ProcessRecord proc = procsToKill.get(i);
13341 Slog.i(TAG, "Removing system update proc: " + proc);
13342 removeProcessLocked(proc, true, false, "system update done");
13346 // Now that we have cleaned up any update processes, we
13347 // are ready to start launching real processes and know that
13348 // we won't trample on them any more.
13349 mProcessesReady = true;
13352 Slog.i(TAG, "System now ready");
13353 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13354 SystemClock.uptimeMillis());
13356 synchronized(this) {
13357 // Make sure we have no pre-ready processes sitting around.
13359 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13360 ResolveInfo ri = mContext.getPackageManager()
13361 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13363 CharSequence errorMsg = null;
13365 ActivityInfo ai = ri.activityInfo;
13366 ApplicationInfo app = ai.applicationInfo;
13367 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13368 mTopAction = Intent.ACTION_FACTORY_TEST;
13370 mTopComponent = new ComponentName(app.packageName,
13373 errorMsg = mContext.getResources().getText(
13374 com.android.internal.R.string.factorytest_not_system);
13377 errorMsg = mContext.getResources().getText(
13378 com.android.internal.R.string.factorytest_no_action);
13380 if (errorMsg != null) {
13383 mTopComponent = null;
13384 Message msg = Message.obtain();
13385 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13386 msg.getData().putCharSequence("msg", errorMsg);
13387 mUiHandler.sendMessage(msg);
13392 retrieveSettings();
13393 final int currentUserId;
13394 synchronized (this) {
13395 currentUserId = mUserController.getCurrentUserIdLocked();
13396 readGrantedUriPermissionsLocked();
13399 if (goingCallback != null) goingCallback.run();
13401 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13402 Integer.toString(currentUserId), currentUserId);
13403 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13404 Integer.toString(currentUserId), currentUserId);
13405 mSystemServiceManager.startUser(currentUserId);
13407 synchronized (this) {
13408 // Only start up encryption-aware persistent apps; once user is
13409 // unlocked we'll come back around and start unaware apps
13410 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13412 // Start up initial activity.
13414 // Enable home activity for system user, so that the system can always boot
13415 if (UserManager.isSplitSystemUser()) {
13416 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13418 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13419 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13420 UserHandle.USER_SYSTEM);
13421 } catch (RemoteException e) {
13422 throw e.rethrowAsRuntimeException();
13425 startHomeActivityLocked(currentUserId, "systemReady");
13428 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13429 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13430 + " data partition or your device will be unstable.");
13431 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13433 } catch (RemoteException e) {
13436 if (!Build.isBuildConsistent()) {
13437 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13438 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13441 long ident = Binder.clearCallingIdentity();
13443 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13444 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13445 | Intent.FLAG_RECEIVER_FOREGROUND);
13446 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13447 broadcastIntentLocked(null, null, intent,
13448 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13449 null, false, false, MY_PID, Process.SYSTEM_UID,
13451 intent = new Intent(Intent.ACTION_USER_STARTING);
13452 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13453 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13454 broadcastIntentLocked(null, null, intent,
13455 null, new IIntentReceiver.Stub() {
13457 public void performReceive(Intent intent, int resultCode, String data,
13458 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13459 throws RemoteException {
13462 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13463 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13464 } catch (Throwable t) {
13465 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13467 Binder.restoreCallingIdentity(ident);
13469 mStackSupervisor.resumeFocusedStackTopActivityLocked();
13470 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13474 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13475 synchronized (this) {
13476 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13480 void skipCurrentReceiverLocked(ProcessRecord app) {
13481 for (BroadcastQueue queue : mBroadcastQueues) {
13482 queue.skipCurrentReceiverLocked(app);
13487 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13488 * The application process will exit immediately after this call returns.
13489 * @param app object of the crashing app, null for the system server
13490 * @param crashInfo describing the exception
13492 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13493 ProcessRecord r = findAppProcess(app, "Crash");
13494 final String processName = app == null ? "system_server"
13495 : (r == null ? "unknown" : r.processName);
13497 handleApplicationCrashInner("crash", r, processName, crashInfo);
13500 /* Native crash reporting uses this inner version because it needs to be somewhat
13501 * decoupled from the AM-managed cleanup lifecycle
13503 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13504 ApplicationErrorReport.CrashInfo crashInfo) {
13505 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13506 UserHandle.getUserId(Binder.getCallingUid()), processName,
13507 r == null ? -1 : r.info.flags,
13508 crashInfo.exceptionClassName,
13509 crashInfo.exceptionMessage,
13510 crashInfo.throwFileName,
13511 crashInfo.throwLineNumber);
13513 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13515 mAppErrors.crashApplication(r, crashInfo);
13518 public void handleApplicationStrictModeViolation(
13521 StrictMode.ViolationInfo info) {
13522 ProcessRecord r = findAppProcess(app, "StrictMode");
13527 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13528 Integer stackFingerprint = info.hashCode();
13529 boolean logIt = true;
13530 synchronized (mAlreadyLoggedViolatedStacks) {
13531 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13533 // TODO: sub-sample into EventLog for these, with
13534 // the info.durationMillis? Then we'd get
13535 // the relative pain numbers, without logging all
13536 // the stack traces repeatedly. We'd want to do
13537 // likewise in the client code, which also does
13538 // dup suppression, before the Binder call.
13540 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13541 mAlreadyLoggedViolatedStacks.clear();
13543 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13547 logStrictModeViolationToDropBox(r, info);
13551 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13552 AppErrorResult result = new AppErrorResult();
13553 synchronized (this) {
13554 final long origId = Binder.clearCallingIdentity();
13556 Message msg = Message.obtain();
13557 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13558 HashMap<String, Object> data = new HashMap<String, Object>();
13559 data.put("result", result);
13560 data.put("app", r);
13561 data.put("violationMask", violationMask);
13562 data.put("info", info);
13564 mUiHandler.sendMessage(msg);
13566 Binder.restoreCallingIdentity(origId);
13568 int res = result.get();
13569 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13573 // Depending on the policy in effect, there could be a bunch of
13574 // these in quick succession so we try to batch these together to
13575 // minimize disk writes, number of dropbox entries, and maximize
13576 // compression, by having more fewer, larger records.
13577 private void logStrictModeViolationToDropBox(
13578 ProcessRecord process,
13579 StrictMode.ViolationInfo info) {
13580 if (info == null) {
13583 final boolean isSystemApp = process == null ||
13584 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13585 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13586 final String processName = process == null ? "unknown" : process.processName;
13587 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13588 final DropBoxManager dbox = (DropBoxManager)
13589 mContext.getSystemService(Context.DROPBOX_SERVICE);
13591 // Exit early if the dropbox isn't configured to accept this report type.
13592 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13594 boolean bufferWasEmpty;
13595 boolean needsFlush;
13596 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13597 synchronized (sb) {
13598 bufferWasEmpty = sb.length() == 0;
13599 appendDropBoxProcessHeaders(process, processName, sb);
13600 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13601 sb.append("System-App: ").append(isSystemApp).append("\n");
13602 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13603 if (info.violationNumThisLoop != 0) {
13604 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13606 if (info.numAnimationsRunning != 0) {
13607 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13609 if (info.broadcastIntentAction != null) {
13610 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13612 if (info.durationMillis != -1) {
13613 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13615 if (info.numInstances != -1) {
13616 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13618 if (info.tags != null) {
13619 for (String tag : info.tags) {
13620 sb.append("Span-Tag: ").append(tag).append("\n");
13624 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13625 sb.append(info.crashInfo.stackTrace);
13628 if (info.message != null) {
13629 sb.append(info.message);
13633 // Only buffer up to ~64k. Various logging bits truncate
13635 needsFlush = (sb.length() > 64 * 1024);
13638 // Flush immediately if the buffer's grown too large, or this
13639 // is a non-system app. Non-system apps are isolated with a
13640 // different tag & policy and not batched.
13642 // Batching is useful during internal testing with
13643 // StrictMode settings turned up high. Without batching,
13644 // thousands of separate files could be created on boot.
13645 if (!isSystemApp || needsFlush) {
13646 new Thread("Error dump: " + dropboxTag) {
13648 public void run() {
13650 synchronized (sb) {
13651 report = sb.toString();
13652 sb.delete(0, sb.length());
13655 if (report.length() != 0) {
13656 dbox.addText(dropboxTag, report);
13663 // System app batching:
13664 if (!bufferWasEmpty) {
13665 // An existing dropbox-writing thread is outstanding, so
13666 // we don't need to start it up. The existing thread will
13667 // catch the buffer appends we just did.
13671 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13672 // (After this point, we shouldn't access AMS internal data structures.)
13673 new Thread("Error dump: " + dropboxTag) {
13675 public void run() {
13676 // 5 second sleep to let stacks arrive and be batched together
13678 Thread.sleep(5000); // 5 seconds
13679 } catch (InterruptedException e) {}
13681 String errorReport;
13682 synchronized (mStrictModeBuffer) {
13683 errorReport = mStrictModeBuffer.toString();
13684 if (errorReport.length() == 0) {
13687 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13688 mStrictModeBuffer.trimToSize();
13690 dbox.addText(dropboxTag, errorReport);
13696 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13697 * @param app object of the crashing app, null for the system server
13698 * @param tag reported by the caller
13699 * @param system whether this wtf is coming from the system
13700 * @param crashInfo describing the context of the error
13701 * @return true if the process should exit immediately (WTF is fatal)
13703 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13704 final ApplicationErrorReport.CrashInfo crashInfo) {
13705 final int callingUid = Binder.getCallingUid();
13706 final int callingPid = Binder.getCallingPid();
13709 // If this is coming from the system, we could very well have low-level
13710 // system locks held, so we want to do this all asynchronously. And we
13711 // never want this to become fatal, so there is that too.
13712 mHandler.post(new Runnable() {
13713 @Override public void run() {
13714 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13720 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13723 if (r != null && r.pid != Process.myPid() &&
13724 Settings.Global.getInt(mContext.getContentResolver(),
13725 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13726 mAppErrors.crashApplication(r, crashInfo);
13733 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13734 final ApplicationErrorReport.CrashInfo crashInfo) {
13735 final ProcessRecord r = findAppProcess(app, "WTF");
13736 final String processName = app == null ? "system_server"
13737 : (r == null ? "unknown" : r.processName);
13739 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13740 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13742 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13748 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13749 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13751 private ProcessRecord findAppProcess(IBinder app, String reason) {
13756 synchronized (this) {
13757 final int NP = mProcessNames.getMap().size();
13758 for (int ip=0; ip<NP; ip++) {
13759 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13760 final int NA = apps.size();
13761 for (int ia=0; ia<NA; ia++) {
13762 ProcessRecord p = apps.valueAt(ia);
13763 if (p.thread != null && p.thread.asBinder() == app) {
13769 Slog.w(TAG, "Can't find mystery application for " + reason
13770 + " from pid=" + Binder.getCallingPid()
13771 + " uid=" + Binder.getCallingUid() + ": " + app);
13777 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13778 * to append various headers to the dropbox log text.
13780 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13781 StringBuilder sb) {
13782 // Watchdog thread ends up invoking this function (with
13783 // a null ProcessRecord) to add the stack file to dropbox.
13784 // Do not acquire a lock on this (am) in such cases, as it
13785 // could cause a potential deadlock, if and when watchdog
13786 // is invoked due to unavailability of lock on am and it
13787 // would prevent watchdog from killing system_server.
13788 if (process == null) {
13789 sb.append("Process: ").append(processName).append("\n");
13792 // Note: ProcessRecord 'process' is guarded by the service
13793 // instance. (notably process.pkgList, which could otherwise change
13794 // concurrently during execution of this method)
13795 synchronized (this) {
13796 sb.append("Process: ").append(processName).append("\n");
13797 int flags = process.info.flags;
13798 IPackageManager pm = AppGlobals.getPackageManager();
13799 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13800 for (int ip=0; ip<process.pkgList.size(); ip++) {
13801 String pkg = process.pkgList.keyAt(ip);
13802 sb.append("Package: ").append(pkg);
13804 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13806 sb.append(" v").append(pi.versionCode);
13807 if (pi.versionName != null) {
13808 sb.append(" (").append(pi.versionName).append(")");
13811 } catch (RemoteException e) {
13812 Slog.e(TAG, "Error getting package info: " + pkg, e);
13819 private static String processClass(ProcessRecord process) {
13820 if (process == null || process.pid == MY_PID) {
13821 return "system_server";
13822 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13823 return "system_app";
13829 private volatile long mWtfClusterStart;
13830 private volatile int mWtfClusterCount;
13833 * Write a description of an error (crash, WTF, ANR) to the drop box.
13834 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13835 * @param process which caused the error, null means the system server
13836 * @param activity which triggered the error, null if unknown
13837 * @param parent activity related to the error, null if unknown
13838 * @param subject line related to the error, null if absent
13839 * @param report in long form describing the error, null if absent
13840 * @param dataFile text file to include in the report, null if none
13841 * @param crashInfo giving an application stack trace, null if absent
13843 public void addErrorToDropBox(String eventType,
13844 ProcessRecord process, String processName, ActivityRecord activity,
13845 ActivityRecord parent, String subject,
13846 final String report, final File dataFile,
13847 final ApplicationErrorReport.CrashInfo crashInfo) {
13848 // NOTE -- this must never acquire the ActivityManagerService lock,
13849 // otherwise the watchdog may be prevented from resetting the system.
13851 final String dropboxTag = processClass(process) + "_" + eventType;
13852 final DropBoxManager dbox = (DropBoxManager)
13853 mContext.getSystemService(Context.DROPBOX_SERVICE);
13855 // Exit early if the dropbox isn't configured to accept this report type.
13856 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13858 // Rate-limit how often we're willing to do the heavy lifting below to
13859 // collect and record logs; currently 5 logs per 10 second period.
13860 final long now = SystemClock.elapsedRealtime();
13861 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13862 mWtfClusterStart = now;
13863 mWtfClusterCount = 1;
13865 if (mWtfClusterCount++ >= 5) return;
13868 final StringBuilder sb = new StringBuilder(1024);
13869 appendDropBoxProcessHeaders(process, processName, sb);
13870 if (process != null) {
13871 sb.append("Foreground: ")
13872 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13875 if (activity != null) {
13876 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13878 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13879 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13881 if (parent != null && parent != activity) {
13882 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13884 if (subject != null) {
13885 sb.append("Subject: ").append(subject).append("\n");
13887 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13888 if (Debug.isDebuggerConnected()) {
13889 sb.append("Debugger: Connected\n");
13893 // Do the rest in a worker thread to avoid blocking the caller on I/O
13894 // (After this point, we shouldn't access AMS internal data structures.)
13895 Thread worker = new Thread("Error dump: " + dropboxTag) {
13897 public void run() {
13898 if (report != null) {
13902 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13903 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13904 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13905 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13907 if (dataFile != null && maxDataFileSize > 0) {
13909 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13910 "\n\n[[TRUNCATED]]"));
13911 } catch (IOException e) {
13912 Slog.e(TAG, "Error reading " + dataFile, e);
13915 if (crashInfo != null && crashInfo.stackTrace != null) {
13916 sb.append(crashInfo.stackTrace);
13922 // Merge several logcat streams, and take the last N lines
13923 InputStreamReader input = null;
13925 java.lang.Process logcat = new ProcessBuilder(
13926 "/system/bin/timeout", "-k", "15s", "10s",
13927 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13928 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13929 .redirectErrorStream(true).start();
13931 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13932 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13933 input = new InputStreamReader(logcat.getInputStream());
13936 char[] buf = new char[8192];
13937 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13938 } catch (IOException e) {
13939 Slog.e(TAG, "Error running logcat", e);
13941 if (input != null) try { input.close(); } catch (IOException e) {}
13945 dbox.addText(dropboxTag, sb.toString());
13949 if (process == null) {
13950 // If process is null, we are being called from some internal code
13951 // and may be about to die -- run this synchronously.
13959 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13960 enforceNotIsolatedCaller("getProcessesInErrorState");
13961 // assume our apps are happy - lazy create the list
13962 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13964 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13965 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13966 int userId = UserHandle.getUserId(Binder.getCallingUid());
13968 synchronized (this) {
13970 // iterate across all processes
13971 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13972 ProcessRecord app = mLruProcesses.get(i);
13973 if (!allUsers && app.userId != userId) {
13976 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13977 // This one's in trouble, so we'll generate a report for it
13978 // crashes are higher priority (in case there's a crash *and* an anr)
13979 ActivityManager.ProcessErrorStateInfo report = null;
13980 if (app.crashing) {
13981 report = app.crashingReport;
13982 } else if (app.notResponding) {
13983 report = app.notRespondingReport;
13986 if (report != null) {
13987 if (errList == null) {
13988 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13990 errList.add(report);
13992 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13993 " crashing = " + app.crashing +
13994 " notResponding = " + app.notResponding);
14003 static int procStateToImportance(int procState, int memAdj,
14004 ActivityManager.RunningAppProcessInfo currApp) {
14005 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14006 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14007 currApp.lru = memAdj;
14014 private void fillInProcMemInfo(ProcessRecord app,
14015 ActivityManager.RunningAppProcessInfo outInfo) {
14016 outInfo.pid = app.pid;
14017 outInfo.uid = app.info.uid;
14018 if (mHeavyWeightProcess == app) {
14019 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14021 if (app.persistent) {
14022 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14024 if (app.activities.size() > 0) {
14025 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14027 outInfo.lastTrimLevel = app.trimMemoryLevel;
14028 int adj = app.curAdj;
14029 int procState = app.curProcState;
14030 outInfo.importance = procStateToImportance(procState, adj, outInfo);
14031 outInfo.importanceReasonCode = app.adjTypeCode;
14032 outInfo.processState = app.curProcState;
14036 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14037 enforceNotIsolatedCaller("getRunningAppProcesses");
14039 final int callingUid = Binder.getCallingUid();
14041 // Lazy instantiation of list
14042 List<ActivityManager.RunningAppProcessInfo> runList = null;
14043 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14044 callingUid) == PackageManager.PERMISSION_GRANTED;
14045 final int userId = UserHandle.getUserId(callingUid);
14046 final boolean allUids = isGetTasksAllowed(
14047 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14049 synchronized (this) {
14050 // Iterate across all processes
14051 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14052 ProcessRecord app = mLruProcesses.get(i);
14053 if ((!allUsers && app.userId != userId)
14054 || (!allUids && app.uid != callingUid)) {
14057 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14058 // Generate process state info for running application
14059 ActivityManager.RunningAppProcessInfo currApp =
14060 new ActivityManager.RunningAppProcessInfo(app.processName,
14061 app.pid, app.getPackageList());
14062 fillInProcMemInfo(app, currApp);
14063 if (app.adjSource instanceof ProcessRecord) {
14064 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14065 currApp.importanceReasonImportance =
14066 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14067 app.adjSourceProcState);
14068 } else if (app.adjSource instanceof ActivityRecord) {
14069 ActivityRecord r = (ActivityRecord)app.adjSource;
14070 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14072 if (app.adjTarget instanceof ComponentName) {
14073 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14075 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14076 // + " lru=" + currApp.lru);
14077 if (runList == null) {
14078 runList = new ArrayList<>();
14080 runList.add(currApp);
14088 public List<ApplicationInfo> getRunningExternalApplications() {
14089 enforceNotIsolatedCaller("getRunningExternalApplications");
14090 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14091 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14092 if (runningApps != null && runningApps.size() > 0) {
14093 Set<String> extList = new HashSet<String>();
14094 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14095 if (app.pkgList != null) {
14096 for (String pkg : app.pkgList) {
14101 IPackageManager pm = AppGlobals.getPackageManager();
14102 for (String pkg : extList) {
14104 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14105 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14108 } catch (RemoteException e) {
14116 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14117 enforceNotIsolatedCaller("getMyMemoryState");
14118 synchronized (this) {
14119 ProcessRecord proc;
14120 synchronized (mPidsSelfLocked) {
14121 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14123 fillInProcMemInfo(proc, outInfo);
14128 public int getMemoryTrimLevel() {
14129 enforceNotIsolatedCaller("getMyMemoryState");
14130 synchronized (this) {
14131 return mLastMemoryLevel;
14136 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14137 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14138 (new ActivityManagerShellCommand(this, false)).exec(
14139 this, in, out, err, args, resultReceiver);
14143 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14144 if (checkCallingPermission(android.Manifest.permission.DUMP)
14145 != PackageManager.PERMISSION_GRANTED) {
14146 pw.println("Permission Denial: can't dump ActivityManager from from pid="
14147 + Binder.getCallingPid()
14148 + ", uid=" + Binder.getCallingUid()
14149 + " without permission "
14150 + android.Manifest.permission.DUMP);
14154 boolean dumpAll = false;
14155 boolean dumpClient = false;
14156 boolean dumpCheckin = false;
14157 boolean dumpCheckinFormat = false;
14158 String dumpPackage = null;
14161 while (opti < args.length) {
14162 String opt = args[opti];
14163 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14167 if ("-a".equals(opt)) {
14169 } else if ("-c".equals(opt)) {
14171 } else if ("-p".equals(opt)) {
14172 if (opti < args.length) {
14173 dumpPackage = args[opti];
14176 pw.println("Error: -p option requires package argument");
14180 } else if ("--checkin".equals(opt)) {
14181 dumpCheckin = dumpCheckinFormat = true;
14182 } else if ("-C".equals(opt)) {
14183 dumpCheckinFormat = true;
14184 } else if ("-h".equals(opt)) {
14185 ActivityManagerShellCommand.dumpHelp(pw, true);
14188 pw.println("Unknown argument: " + opt + "; use -h for help");
14192 long origId = Binder.clearCallingIdentity();
14193 boolean more = false;
14194 // Is the caller requesting to dump a particular piece of data?
14195 if (opti < args.length) {
14196 String cmd = args[opti];
14198 if ("activities".equals(cmd) || "a".equals(cmd)) {
14199 synchronized (this) {
14200 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14202 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14203 synchronized (this) {
14204 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14206 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14209 if (opti >= args.length) {
14211 newArgs = EMPTY_STRING_ARRAY;
14213 dumpPackage = args[opti];
14215 newArgs = new String[args.length - opti];
14216 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14217 args.length - opti);
14219 synchronized (this) {
14220 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14222 } else if ("broadcast-stats".equals(cmd)) {
14225 if (opti >= args.length) {
14227 newArgs = EMPTY_STRING_ARRAY;
14229 dumpPackage = args[opti];
14231 newArgs = new String[args.length - opti];
14232 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14233 args.length - opti);
14235 synchronized (this) {
14236 if (dumpCheckinFormat) {
14237 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14240 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14243 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14246 if (opti >= args.length) {
14248 newArgs = EMPTY_STRING_ARRAY;
14250 dumpPackage = args[opti];
14252 newArgs = new String[args.length - opti];
14253 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14254 args.length - opti);
14256 synchronized (this) {
14257 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14259 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14262 if (opti >= args.length) {
14264 newArgs = EMPTY_STRING_ARRAY;
14266 dumpPackage = args[opti];
14268 newArgs = new String[args.length - opti];
14269 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14270 args.length - opti);
14272 synchronized (this) {
14273 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14275 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14276 synchronized (this) {
14277 dumpOomLocked(fd, pw, args, opti, true);
14279 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14280 synchronized (this) {
14281 dumpPermissionsLocked(fd, pw, args, opti, true, null);
14283 } else if ("provider".equals(cmd)) {
14286 if (opti >= args.length) {
14288 newArgs = EMPTY_STRING_ARRAY;
14292 newArgs = new String[args.length - opti];
14293 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14295 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14296 pw.println("No providers match: " + name);
14297 pw.println("Use -h for help.");
14299 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14300 synchronized (this) {
14301 dumpProvidersLocked(fd, pw, args, opti, true, null);
14303 } else if ("service".equals(cmd)) {
14306 if (opti >= args.length) {
14308 newArgs = EMPTY_STRING_ARRAY;
14312 newArgs = new String[args.length - opti];
14313 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14314 args.length - opti);
14316 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14317 pw.println("No services match: " + name);
14318 pw.println("Use -h for help.");
14320 } else if ("package".equals(cmd)) {
14322 if (opti >= args.length) {
14323 pw.println("package: no package name specified");
14324 pw.println("Use -h for help.");
14326 dumpPackage = args[opti];
14328 newArgs = new String[args.length - opti];
14329 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14330 args.length - opti);
14335 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14336 synchronized (this) {
14337 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14339 } else if ("services".equals(cmd) || "s".equals(cmd)) {
14341 ActiveServices.ServiceDumper dumper;
14342 synchronized (this) {
14343 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14346 dumper.dumpWithClient();
14348 synchronized (this) {
14349 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14350 dumpPackage).dumpLocked();
14353 } else if ("locks".equals(cmd)) {
14354 LockGuard.dump(fd, pw, args);
14356 // Dumping a single activity?
14357 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14358 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14359 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14361 pw.println("Bad activity command, or no activities match: " + cmd);
14362 pw.println("Use -h for help.");
14367 Binder.restoreCallingIdentity(origId);
14372 // No piece of data specified, dump everything.
14373 if (dumpCheckinFormat) {
14374 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14375 } else if (dumpClient) {
14376 ActiveServices.ServiceDumper sdumper;
14377 synchronized (this) {
14378 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14381 pw.println("-------------------------------------------------------------------------------");
14383 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14386 pw.println("-------------------------------------------------------------------------------");
14388 if (dumpAll || dumpPackage != null) {
14389 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14392 pw.println("-------------------------------------------------------------------------------");
14395 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14398 pw.println("-------------------------------------------------------------------------------");
14400 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14403 pw.println("-------------------------------------------------------------------------------");
14405 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14408 sdumper.dumpWithClient();
14410 synchronized (this) {
14412 pw.println("-------------------------------------------------------------------------------");
14414 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14417 pw.println("-------------------------------------------------------------------------------");
14419 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14420 if (mAssociations.size() > 0) {
14423 pw.println("-------------------------------------------------------------------------------");
14425 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14429 pw.println("-------------------------------------------------------------------------------");
14431 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14435 synchronized (this) {
14436 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14439 pw.println("-------------------------------------------------------------------------------");
14441 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14444 pw.println("-------------------------------------------------------------------------------");
14446 if (dumpAll || dumpPackage != null) {
14447 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14450 pw.println("-------------------------------------------------------------------------------");
14453 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14456 pw.println("-------------------------------------------------------------------------------");
14458 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14461 pw.println("-------------------------------------------------------------------------------");
14463 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14467 pw.println("-------------------------------------------------------------------------------");
14469 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14472 pw.println("-------------------------------------------------------------------------------");
14474 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14475 if (mAssociations.size() > 0) {
14478 pw.println("-------------------------------------------------------------------------------");
14480 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14484 pw.println("-------------------------------------------------------------------------------");
14486 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14489 Binder.restoreCallingIdentity(origId);
14492 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14493 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14494 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14496 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14498 boolean needSep = printedAnything;
14500 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14501 dumpPackage, needSep, " mFocusedActivity: ");
14503 printedAnything = true;
14507 if (dumpPackage == null) {
14512 printedAnything = true;
14513 mStackSupervisor.dump(pw, " ");
14516 if (!printedAnything) {
14517 pw.println(" (nothing)");
14521 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14522 int opti, boolean dumpAll, String dumpPackage) {
14523 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14525 boolean printedAnything = false;
14527 if (mRecentTasks != null && mRecentTasks.size() > 0) {
14528 boolean printedHeader = false;
14530 final int N = mRecentTasks.size();
14531 for (int i=0; i<N; i++) {
14532 TaskRecord tr = mRecentTasks.get(i);
14533 if (dumpPackage != null) {
14534 if (tr.realActivity == null ||
14535 !dumpPackage.equals(tr.realActivity)) {
14539 if (!printedHeader) {
14540 pw.println(" Recent tasks:");
14541 printedHeader = true;
14542 printedAnything = true;
14544 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
14547 mRecentTasks.get(i).dump(pw, " ");
14552 if (!printedAnything) {
14553 pw.println(" (nothing)");
14557 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14558 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14559 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14562 if (dumpPackage != null) {
14563 IPackageManager pm = AppGlobals.getPackageManager();
14565 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14566 } catch (RemoteException e) {
14570 boolean printedAnything = false;
14572 final long now = SystemClock.uptimeMillis();
14574 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14575 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14576 = mAssociations.valueAt(i1);
14577 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14578 SparseArray<ArrayMap<String, Association>> sourceUids
14579 = targetComponents.valueAt(i2);
14580 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14581 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14582 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14583 Association ass = sourceProcesses.valueAt(i4);
14584 if (dumpPackage != null) {
14585 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14586 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14590 printedAnything = true;
14592 pw.print(ass.mTargetProcess);
14594 UserHandle.formatUid(pw, ass.mTargetUid);
14596 pw.print(ass.mSourceProcess);
14598 UserHandle.formatUid(pw, ass.mSourceUid);
14601 pw.print(ass.mTargetComponent.flattenToShortString());
14604 long dur = ass.mTime;
14605 if (ass.mNesting > 0) {
14606 dur += now - ass.mStartTime;
14608 TimeUtils.formatDuration(dur, pw);
14610 pw.print(ass.mCount);
14611 pw.print(" times)");
14613 for (int i=0; i<ass.mStateTimes.length; i++) {
14614 long amt = ass.mStateTimes[i];
14615 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14616 amt += now - ass.mLastStateUptime;
14620 pw.print(ProcessList.makeProcStateString(
14621 i + ActivityManager.MIN_PROCESS_STATE));
14623 TimeUtils.formatDuration(amt, pw);
14624 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14630 if (ass.mNesting > 0) {
14631 pw.print(" Currently active: ");
14632 TimeUtils.formatDuration(now - ass.mStartTime, pw);
14641 if (!printedAnything) {
14642 pw.println(" (nothing)");
14646 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14647 String header, boolean needSep) {
14648 boolean printed = false;
14649 int whichAppId = -1;
14650 if (dumpPackage != null) {
14652 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14654 whichAppId = UserHandle.getAppId(info.uid);
14655 } catch (NameNotFoundException e) {
14656 e.printStackTrace();
14659 for (int i=0; i<uids.size(); i++) {
14660 UidRecord uidRec = uids.valueAt(i);
14661 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14670 pw.println(header);
14673 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14674 pw.print(": "); pw.println(uidRec);
14679 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14680 int opti, boolean dumpAll, String dumpPackage) {
14681 boolean needSep = false;
14682 boolean printedAnything = false;
14685 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14688 final int NP = mProcessNames.getMap().size();
14689 for (int ip=0; ip<NP; ip++) {
14690 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14691 final int NA = procs.size();
14692 for (int ia=0; ia<NA; ia++) {
14693 ProcessRecord r = procs.valueAt(ia);
14694 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14698 pw.println(" All known processes:");
14700 printedAnything = true;
14702 pw.print(r.persistent ? " *PERS*" : " *APP*");
14703 pw.print(" UID "); pw.print(procs.keyAt(ia));
14704 pw.print(" "); pw.println(r);
14706 if (r.persistent) {
14713 if (mIsolatedProcesses.size() > 0) {
14714 boolean printed = false;
14715 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14716 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14717 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14724 pw.println(" Isolated process list (sorted by uid):");
14725 printedAnything = true;
14729 pw.println(String.format("%sIsolated #%2d: %s",
14730 " ", i, r.toString()));
14734 if (mActiveUids.size() > 0) {
14735 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14736 printedAnything = needSep = true;
14739 if (mValidateUids.size() > 0) {
14740 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14741 printedAnything = needSep = true;
14745 if (mLruProcesses.size() > 0) {
14749 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14750 pw.print(" total, non-act at ");
14751 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14752 pw.print(", non-svc at ");
14753 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14755 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14757 printedAnything = true;
14760 if (dumpAll || dumpPackage != null) {
14761 synchronized (mPidsSelfLocked) {
14762 boolean printed = false;
14763 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14764 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14765 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14769 if (needSep) pw.println();
14771 pw.println(" PID mappings:");
14773 printedAnything = true;
14775 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14776 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14781 if (mForegroundProcesses.size() > 0) {
14782 synchronized (mPidsSelfLocked) {
14783 boolean printed = false;
14784 for (int i=0; i<mForegroundProcesses.size(); i++) {
14785 ProcessRecord r = mPidsSelfLocked.get(
14786 mForegroundProcesses.valueAt(i).pid);
14787 if (dumpPackage != null && (r == null
14788 || !r.pkgList.containsKey(dumpPackage))) {
14792 if (needSep) pw.println();
14794 pw.println(" Foreground Processes:");
14796 printedAnything = true;
14798 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14799 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14804 if (mPersistentStartingProcesses.size() > 0) {
14805 if (needSep) pw.println();
14807 printedAnything = true;
14808 pw.println(" Persisent processes that are starting:");
14809 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14810 "Starting Norm", "Restarting PERS", dumpPackage);
14813 if (mRemovedProcesses.size() > 0) {
14814 if (needSep) pw.println();
14816 printedAnything = true;
14817 pw.println(" Processes that are being removed:");
14818 dumpProcessList(pw, this, mRemovedProcesses, " ",
14819 "Removed Norm", "Removed PERS", dumpPackage);
14822 if (mProcessesOnHold.size() > 0) {
14823 if (needSep) pw.println();
14825 printedAnything = true;
14826 pw.println(" Processes that are on old until the system is ready:");
14827 dumpProcessList(pw, this, mProcessesOnHold, " ",
14828 "OnHold Norm", "OnHold PERS", dumpPackage);
14831 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14833 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14835 printedAnything = true;
14838 if (dumpPackage == null) {
14841 mUserController.dump(pw, dumpAll);
14843 if (mHomeProcess != null && (dumpPackage == null
14844 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14849 pw.println(" mHomeProcess: " + mHomeProcess);
14851 if (mPreviousProcess != null && (dumpPackage == null
14852 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14857 pw.println(" mPreviousProcess: " + mPreviousProcess);
14860 StringBuilder sb = new StringBuilder(128);
14861 sb.append(" mPreviousProcessVisibleTime: ");
14862 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14865 if (mHeavyWeightProcess != null && (dumpPackage == null
14866 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14871 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14873 if (dumpPackage == null) {
14874 pw.println(" mConfiguration: " + mConfiguration);
14877 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14878 if (mCompatModePackages.getPackages().size() > 0) {
14879 boolean printed = false;
14880 for (Map.Entry<String, Integer> entry
14881 : mCompatModePackages.getPackages().entrySet()) {
14882 String pkg = entry.getKey();
14883 int mode = entry.getValue();
14884 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14888 pw.println(" mScreenCompatPackages:");
14891 pw.print(" "); pw.print(pkg); pw.print(": ");
14892 pw.print(mode); pw.println();
14896 if (dumpPackage == null) {
14897 pw.println(" mWakefulness="
14898 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14899 pw.println(" mSleepTokens=" + mSleepTokens);
14900 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14901 + lockScreenShownToString());
14902 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14903 if (mRunningVoice != null) {
14904 pw.println(" mRunningVoice=" + mRunningVoice);
14905 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14908 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14909 || mOrigWaitForDebugger) {
14910 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14911 || dumpPackage.equals(mOrigDebugApp)) {
14916 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14917 + " mDebugTransient=" + mDebugTransient
14918 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14921 if (mCurAppTimeTracker != null) {
14922 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14924 if (mMemWatchProcesses.getMap().size() > 0) {
14925 pw.println(" Mem watch processes:");
14926 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14927 = mMemWatchProcesses.getMap();
14928 for (int i=0; i<procs.size(); i++) {
14929 final String proc = procs.keyAt(i);
14930 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14931 for (int j=0; j<uids.size(); j++) {
14936 StringBuilder sb = new StringBuilder();
14937 sb.append(" ").append(proc).append('/');
14938 UserHandle.formatUid(sb, uids.keyAt(j));
14939 Pair<Long, String> val = uids.valueAt(j);
14940 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14941 if (val.second != null) {
14942 sb.append(", report to ").append(val.second);
14944 pw.println(sb.toString());
14947 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14948 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14949 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14950 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14952 if (mTrackAllocationApp != null) {
14953 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14958 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14961 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14962 || mProfileFd != null) {
14963 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14968 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14969 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14970 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14971 + mAutoStopProfiler);
14972 pw.println(" mProfileType=" + mProfileType);
14975 if (mNativeDebuggingApp != null) {
14976 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14981 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14984 if (dumpPackage == null) {
14985 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14986 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14987 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14989 if (mController != null) {
14990 pw.println(" mController=" + mController
14991 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14994 pw.println(" Total persistent processes: " + numPers);
14995 pw.println(" mProcessesReady=" + mProcessesReady
14996 + " mSystemReady=" + mSystemReady
14997 + " mBooted=" + mBooted
14998 + " mFactoryTest=" + mFactoryTest);
14999 pw.println(" mBooting=" + mBooting
15000 + " mCallFinishBooting=" + mCallFinishBooting
15001 + " mBootAnimationComplete=" + mBootAnimationComplete);
15002 pw.print(" mLastPowerCheckRealtime=");
15003 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15005 pw.print(" mLastPowerCheckUptime=");
15006 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15008 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15009 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15010 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15011 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
15012 + " (" + mLruProcesses.size() + " total)"
15013 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15014 + " mNumServiceProcs=" + mNumServiceProcs
15015 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15016 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
15017 + " mLastMemoryLevel=" + mLastMemoryLevel
15018 + " mLastNumProcesses=" + mLastNumProcesses);
15019 long now = SystemClock.uptimeMillis();
15020 pw.print(" mLastIdleTime=");
15021 TimeUtils.formatDuration(now, mLastIdleTime, pw);
15022 pw.print(" mLowRamSinceLastIdle=");
15023 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15028 if (!printedAnything) {
15029 pw.println(" (nothing)");
15033 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15034 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15035 if (mProcessesToGc.size() > 0) {
15036 boolean printed = false;
15037 long now = SystemClock.uptimeMillis();
15038 for (int i=0; i<mProcessesToGc.size(); i++) {
15039 ProcessRecord proc = mProcessesToGc.get(i);
15040 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15044 if (needSep) pw.println();
15046 pw.println(" Processes that are waiting to GC:");
15049 pw.print(" Process "); pw.println(proc);
15050 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
15051 pw.print(", last gced=");
15052 pw.print(now-proc.lastRequestedGc);
15053 pw.print(" ms ago, last lowMem=");
15054 pw.print(now-proc.lastLowMemory);
15055 pw.println(" ms ago");
15062 void printOomLevel(PrintWriter pw, String name, int adj) {
15066 if (adj < 10) pw.print(' ');
15068 if (adj > -10) pw.print(' ');
15074 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15078 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15079 int opti, boolean dumpAll) {
15080 boolean needSep = false;
15082 if (mLruProcesses.size() > 0) {
15083 if (needSep) pw.println();
15085 pw.println(" OOM levels:");
15086 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15087 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15088 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15089 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15090 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15091 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15092 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15093 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15094 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15095 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15096 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15097 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15098 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15099 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15101 if (needSep) pw.println();
15102 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
15103 pw.print(" total, non-act at ");
15104 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15105 pw.print(", non-svc at ");
15106 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15108 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
15112 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15115 pw.println(" mHomeProcess: " + mHomeProcess);
15116 pw.println(" mPreviousProcess: " + mPreviousProcess);
15117 if (mHeavyWeightProcess != null) {
15118 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15125 * There are three ways to call this:
15126 * - no provider specified: dump all the providers
15127 * - a flattened component name that matched an existing provider was specified as the
15128 * first arg: dump that one provider
15129 * - the first arg isn't the flattened component name of an existing provider:
15130 * dump all providers whose component contains the first arg as a substring
15132 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15133 int opti, boolean dumpAll) {
15134 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15137 static class ItemMatcher {
15138 ArrayList<ComponentName> components;
15139 ArrayList<String> strings;
15140 ArrayList<Integer> objects;
15147 void build(String name) {
15148 ComponentName componentName = ComponentName.unflattenFromString(name);
15149 if (componentName != null) {
15150 if (components == null) {
15151 components = new ArrayList<ComponentName>();
15153 components.add(componentName);
15157 // Not a '/' separated full component name; maybe an object ID?
15159 objectId = Integer.parseInt(name, 16);
15160 if (objects == null) {
15161 objects = new ArrayList<Integer>();
15163 objects.add(objectId);
15165 } catch (RuntimeException e) {
15166 // Not an integer; just do string match.
15167 if (strings == null) {
15168 strings = new ArrayList<String>();
15176 int build(String[] args, int opti) {
15177 for (; opti<args.length; opti++) {
15178 String name = args[opti];
15179 if ("--".equals(name)) {
15187 boolean match(Object object, ComponentName comp) {
15191 if (components != null) {
15192 for (int i=0; i<components.size(); i++) {
15193 if (components.get(i).equals(comp)) {
15198 if (objects != null) {
15199 for (int i=0; i<objects.size(); i++) {
15200 if (System.identityHashCode(object) == objects.get(i)) {
15205 if (strings != null) {
15206 String flat = comp.flattenToString();
15207 for (int i=0; i<strings.size(); i++) {
15208 if (flat.contains(strings.get(i))) {
15218 * There are three things that cmd can be:
15219 * - a flattened component name that matches an existing activity
15220 * - the cmd arg isn't the flattened component name of an existing activity:
15221 * dump all activity whose component contains the cmd as a substring
15222 * - A hex number of the ActivityRecord object instance.
15224 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15225 int opti, boolean dumpAll) {
15226 ArrayList<ActivityRecord> activities;
15228 synchronized (this) {
15229 activities = mStackSupervisor.getDumpActivitiesLocked(name);
15232 if (activities.size() <= 0) {
15236 String[] newArgs = new String[args.length - opti];
15237 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15239 TaskRecord lastTask = null;
15240 boolean needSep = false;
15241 for (int i=activities.size()-1; i>=0; i--) {
15242 ActivityRecord r = activities.get(i);
15247 synchronized (this) {
15248 if (lastTask != r.task) {
15250 pw.print("TASK "); pw.print(lastTask.affinity);
15251 pw.print(" id="); pw.println(lastTask.taskId);
15253 lastTask.dump(pw, " ");
15257 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
15263 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15264 * there is a thread associated with the activity.
15266 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15267 final ActivityRecord r, String[] args, boolean dumpAll) {
15268 String innerPrefix = prefix + " ";
15269 synchronized (this) {
15270 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15271 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15273 if (r.app != null) pw.println(r.app.pid);
15274 else pw.println("(not running)");
15276 r.dump(pw, innerPrefix);
15279 if (r.app != null && r.app.thread != null) {
15280 // flush anything that is already in the PrintWriter since the thread is going
15281 // to write to the file descriptor directly
15284 TransferPipe tp = new TransferPipe();
15286 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15287 r.appToken, innerPrefix, args);
15292 } catch (IOException e) {
15293 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15294 } catch (RemoteException e) {
15295 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15300 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15301 int opti, boolean dumpAll, String dumpPackage) {
15302 boolean needSep = false;
15303 boolean onlyHistory = false;
15304 boolean printedAnything = false;
15306 if ("history".equals(dumpPackage)) {
15307 if (opti < args.length && "-s".equals(args[opti])) {
15310 onlyHistory = true;
15311 dumpPackage = null;
15314 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15315 if (!onlyHistory && dumpAll) {
15316 if (mRegisteredReceivers.size() > 0) {
15317 boolean printed = false;
15318 Iterator it = mRegisteredReceivers.values().iterator();
15319 while (it.hasNext()) {
15320 ReceiverList r = (ReceiverList)it.next();
15321 if (dumpPackage != null && (r.app == null ||
15322 !dumpPackage.equals(r.app.info.packageName))) {
15326 pw.println(" Registered Receivers:");
15329 printedAnything = true;
15331 pw.print(" * "); pw.println(r);
15336 if (mReceiverResolver.dump(pw, needSep ?
15337 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
15338 " ", dumpPackage, false, false)) {
15340 printedAnything = true;
15344 for (BroadcastQueue q : mBroadcastQueues) {
15345 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15346 printedAnything |= needSep;
15351 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15352 for (int user=0; user<mStickyBroadcasts.size(); user++) {
15357 printedAnything = true;
15358 pw.print(" Sticky broadcasts for user ");
15359 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15360 StringBuilder sb = new StringBuilder(128);
15361 for (Map.Entry<String, ArrayList<Intent>> ent
15362 : mStickyBroadcasts.valueAt(user).entrySet()) {
15363 pw.print(" * Sticky action "); pw.print(ent.getKey());
15366 ArrayList<Intent> intents = ent.getValue();
15367 final int N = intents.size();
15368 for (int i=0; i<N; i++) {
15370 sb.append(" Intent: ");
15371 intents.get(i).toShortString(sb, false, true, false, false);
15372 pw.println(sb.toString());
15373 Bundle bundle = intents.get(i).getExtras();
15374 if (bundle != null) {
15376 pw.println(bundle.toString());
15386 if (!onlyHistory && dumpAll) {
15388 for (BroadcastQueue queue : mBroadcastQueues) {
15389 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
15390 + queue.mBroadcastsScheduled);
15392 pw.println(" mHandler:");
15393 mHandler.dump(new PrintWriterPrinter(pw), " ");
15395 printedAnything = true;
15398 if (!printedAnything) {
15399 pw.println(" (nothing)");
15403 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15404 int opti, boolean dumpAll, String dumpPackage) {
15405 if (mCurBroadcastStats == null) {
15409 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15410 final long now = SystemClock.elapsedRealtime();
15411 if (mLastBroadcastStats != null) {
15412 pw.print(" Last stats (from ");
15413 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15415 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15417 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15418 - mLastBroadcastStats.mStartUptime, pw);
15419 pw.println(" uptime):");
15420 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15421 pw.println(" (nothing)");
15425 pw.print(" Current stats (from ");
15426 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15427 pw.print(" to now, ");
15428 TimeUtils.formatDuration(SystemClock.uptimeMillis()
15429 - mCurBroadcastStats.mStartUptime, pw);
15430 pw.println(" uptime):");
15431 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15432 pw.println(" (nothing)");
15436 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15437 int opti, boolean fullCheckin, String dumpPackage) {
15438 if (mCurBroadcastStats == null) {
15442 if (mLastBroadcastStats != null) {
15443 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15445 mLastBroadcastStats = null;
15449 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15451 mCurBroadcastStats = null;
15455 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15456 int opti, boolean dumpAll, String dumpPackage) {
15458 boolean printedAnything = false;
15460 ItemMatcher matcher = new ItemMatcher();
15461 matcher.build(args, opti);
15463 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15465 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15466 printedAnything |= needSep;
15468 if (mLaunchingProviders.size() > 0) {
15469 boolean printed = false;
15470 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15471 ContentProviderRecord r = mLaunchingProviders.get(i);
15472 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15476 if (needSep) pw.println();
15478 pw.println(" Launching content providers:");
15480 printedAnything = true;
15482 pw.print(" Launching #"); pw.print(i); pw.print(": ");
15487 if (!printedAnything) {
15488 pw.println(" (nothing)");
15492 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15493 int opti, boolean dumpAll, String dumpPackage) {
15494 boolean needSep = false;
15495 boolean printedAnything = false;
15497 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15499 if (mGrantedUriPermissions.size() > 0) {
15500 boolean printed = false;
15502 if (dumpPackage != null) {
15504 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15505 MATCH_UNINSTALLED_PACKAGES, 0);
15506 } catch (NameNotFoundException e) {
15510 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15511 int uid = mGrantedUriPermissions.keyAt(i);
15512 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15515 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15517 if (needSep) pw.println();
15519 pw.println(" Granted Uri Permissions:");
15521 printedAnything = true;
15523 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
15524 for (UriPermission perm : perms.values()) {
15525 pw.print(" "); pw.println(perm);
15527 perm.dump(pw, " ");
15533 if (!printedAnything) {
15534 pw.println(" (nothing)");
15538 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15539 int opti, boolean dumpAll, String dumpPackage) {
15540 boolean printed = false;
15542 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15544 if (mIntentSenderRecords.size() > 0) {
15545 Iterator<WeakReference<PendingIntentRecord>> it
15546 = mIntentSenderRecords.values().iterator();
15547 while (it.hasNext()) {
15548 WeakReference<PendingIntentRecord> ref = it.next();
15549 PendingIntentRecord rec = ref != null ? ref.get(): null;
15550 if (dumpPackage != null && (rec == null
15551 || !dumpPackage.equals(rec.key.packageName))) {
15556 pw.print(" * "); pw.println(rec);
15561 pw.print(" * "); pw.println(ref);
15567 pw.println(" (nothing)");
15571 private static final int dumpProcessList(PrintWriter pw,
15572 ActivityManagerService service, List list,
15573 String prefix, String normalLabel, String persistentLabel,
15574 String dumpPackage) {
15576 final int N = list.size()-1;
15577 for (int i=N; i>=0; i--) {
15578 ProcessRecord r = (ProcessRecord)list.get(i);
15579 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15582 pw.println(String.format("%s%s #%2d: %s",
15583 prefix, (r.persistent ? persistentLabel : normalLabel),
15585 if (r.persistent) {
15592 private static final boolean dumpProcessOomList(PrintWriter pw,
15593 ActivityManagerService service, List<ProcessRecord> origList,
15594 String prefix, String normalLabel, String persistentLabel,
15595 boolean inclDetails, String dumpPackage) {
15597 ArrayList<Pair<ProcessRecord, Integer>> list
15598 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15599 for (int i=0; i<origList.size(); i++) {
15600 ProcessRecord r = origList.get(i);
15601 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15604 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15607 if (list.size() <= 0) {
15611 Comparator<Pair<ProcessRecord, Integer>> comparator
15612 = new Comparator<Pair<ProcessRecord, Integer>>() {
15614 public int compare(Pair<ProcessRecord, Integer> object1,
15615 Pair<ProcessRecord, Integer> object2) {
15616 if (object1.first.setAdj != object2.first.setAdj) {
15617 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15619 if (object1.first.setProcState != object2.first.setProcState) {
15620 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15622 if (object1.second.intValue() != object2.second.intValue()) {
15623 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15629 Collections.sort(list, comparator);
15631 final long curRealtime = SystemClock.elapsedRealtime();
15632 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15633 final long curUptime = SystemClock.uptimeMillis();
15634 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15636 for (int i=list.size()-1; i>=0; i--) {
15637 ProcessRecord r = list.get(i).first;
15638 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15640 switch (r.setSchedGroup) {
15641 case ProcessList.SCHED_GROUP_BACKGROUND:
15644 case ProcessList.SCHED_GROUP_DEFAULT:
15647 case ProcessList.SCHED_GROUP_TOP_APP:
15655 if (r.foregroundActivities) {
15657 } else if (r.foregroundServices) {
15662 String procState = ProcessList.makeProcStateString(r.curProcState);
15664 pw.print(r.persistent ? persistentLabel : normalLabel);
15666 int num = (origList.size()-1)-list.get(i).second;
15667 if (num < 10) pw.print(' ');
15672 pw.print(schedGroup);
15674 pw.print(foreground);
15676 pw.print(procState);
15678 if (r.trimMemoryLevel < 10) pw.print(' ');
15679 pw.print(r.trimMemoryLevel);
15681 pw.print(r.toShortString());
15683 pw.print(r.adjType);
15685 if (r.adjSource != null || r.adjTarget != null) {
15688 if (r.adjTarget instanceof ComponentName) {
15689 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15690 } else if (r.adjTarget != null) {
15691 pw.print(r.adjTarget.toString());
15693 pw.print("{null}");
15696 if (r.adjSource instanceof ProcessRecord) {
15698 pw.print(((ProcessRecord)r.adjSource).toShortString());
15700 } else if (r.adjSource != null) {
15701 pw.println(r.adjSource.toString());
15703 pw.println("{null}");
15709 pw.print("oom: max="); pw.print(r.maxAdj);
15710 pw.print(" curRaw="); pw.print(r.curRawAdj);
15711 pw.print(" setRaw="); pw.print(r.setRawAdj);
15712 pw.print(" cur="); pw.print(r.curAdj);
15713 pw.print(" set="); pw.println(r.setAdj);
15716 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15717 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15718 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15719 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15720 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15724 pw.print("cached="); pw.print(r.cached);
15725 pw.print(" empty="); pw.print(r.empty);
15726 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15728 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15729 if (r.lastWakeTime != 0) {
15731 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15732 synchronized (stats) {
15733 wtime = stats.getProcessWakeTime(r.info.uid,
15734 r.pid, curRealtime);
15736 long timeUsed = wtime - r.lastWakeTime;
15739 pw.print("keep awake over ");
15740 TimeUtils.formatDuration(realtimeSince, pw);
15741 pw.print(" used ");
15742 TimeUtils.formatDuration(timeUsed, pw);
15744 pw.print((timeUsed*100)/realtimeSince);
15747 if (r.lastCpuTime != 0) {
15748 long timeUsed = r.curCpuTime - r.lastCpuTime;
15751 pw.print("run cpu over ");
15752 TimeUtils.formatDuration(uptimeSince, pw);
15753 pw.print(" used ");
15754 TimeUtils.formatDuration(timeUsed, pw);
15756 pw.print((timeUsed*100)/uptimeSince);
15765 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15767 ArrayList<ProcessRecord> procs;
15768 synchronized (this) {
15769 if (args != null && args.length > start
15770 && args[start].charAt(0) != '-') {
15771 procs = new ArrayList<ProcessRecord>();
15774 pid = Integer.parseInt(args[start]);
15775 } catch (NumberFormatException e) {
15777 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15778 ProcessRecord proc = mLruProcesses.get(i);
15779 if (proc.pid == pid) {
15781 } else if (allPkgs && proc.pkgList != null
15782 && proc.pkgList.containsKey(args[start])) {
15784 } else if (proc.processName.equals(args[start])) {
15788 if (procs.size() <= 0) {
15792 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15798 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15799 PrintWriter pw, String[] args) {
15800 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15801 if (procs == null) {
15802 pw.println("No process found for: " + args[0]);
15806 long uptime = SystemClock.uptimeMillis();
15807 long realtime = SystemClock.elapsedRealtime();
15808 pw.println("Applications Graphics Acceleration Info:");
15809 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15811 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15812 ProcessRecord r = procs.get(i);
15813 if (r.thread != null) {
15814 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15817 TransferPipe tp = new TransferPipe();
15819 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15824 } catch (IOException e) {
15825 pw.println("Failure while dumping the app: " + r);
15827 } catch (RemoteException e) {
15828 pw.println("Got a RemoteException while dumping the app " + r);
15835 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15836 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15837 if (procs == null) {
15838 pw.println("No process found for: " + args[0]);
15842 pw.println("Applications Database Info:");
15844 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15845 ProcessRecord r = procs.get(i);
15846 if (r.thread != null) {
15847 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15850 TransferPipe tp = new TransferPipe();
15852 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15857 } catch (IOException e) {
15858 pw.println("Failure while dumping the app: " + r);
15860 } catch (RemoteException e) {
15861 pw.println("Got a RemoteException while dumping the app " + r);
15868 final static class MemItem {
15869 final boolean isProc;
15870 final String label;
15871 final String shortLabel;
15873 final long swapPss;
15875 final boolean hasActivities;
15876 ArrayList<MemItem> subitems;
15878 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15879 boolean _hasActivities) {
15882 shortLabel = _shortLabel;
15884 swapPss = _swapPss;
15886 hasActivities = _hasActivities;
15889 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15892 shortLabel = _shortLabel;
15894 swapPss = _swapPss;
15896 hasActivities = false;
15900 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15901 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15902 if (sort && !isCompact) {
15903 Collections.sort(items, new Comparator<MemItem>() {
15905 public int compare(MemItem lhs, MemItem rhs) {
15906 if (lhs.pss < rhs.pss) {
15908 } else if (lhs.pss > rhs.pss) {
15916 for (int i=0; i<items.size(); i++) {
15917 MemItem mi = items.get(i);
15920 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15921 mi.label, stringifyKBSize(mi.swapPss));
15923 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15925 } else if (mi.isProc) {
15926 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15927 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15928 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15929 pw.println(mi.hasActivities ? ",a" : ",e");
15931 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15932 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15934 if (mi.subitems != null) {
15935 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15936 true, isCompact, dumpSwapPss);
15941 // These are in KB.
15942 static final long[] DUMP_MEM_BUCKETS = new long[] {
15943 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15944 120*1024, 160*1024, 200*1024,
15945 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15946 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15949 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15950 boolean stackLike) {
15951 int start = label.lastIndexOf('.');
15952 if (start >= 0) start++;
15954 int end = label.length();
15955 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15956 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15957 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15958 out.append(bucket);
15959 out.append(stackLike ? "MB." : "MB ");
15960 out.append(label, start, end);
15964 out.append(memKB/1024);
15965 out.append(stackLike ? "MB." : "MB ");
15966 out.append(label, start, end);
15969 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15970 ProcessList.NATIVE_ADJ,
15971 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15972 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15973 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15974 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15975 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15976 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15978 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15980 "System", "Persistent", "Persistent Service", "Foreground",
15981 "Visible", "Perceptible",
15982 "Heavy Weight", "Backup",
15983 "A Services", "Home",
15984 "Previous", "B Services", "Cached"
15986 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15988 "sys", "pers", "persvc", "fore",
15991 "servicea", "home",
15992 "prev", "serviceb", "cached"
15995 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15996 long realtime, boolean isCheckinRequest, boolean isCompact) {
15998 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16000 if (isCheckinRequest || isCompact) {
16001 // short checkin version
16002 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16004 pw.println("Applications Memory Usage (in Kilobytes):");
16005 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16009 private static final int KSM_SHARED = 0;
16010 private static final int KSM_SHARING = 1;
16011 private static final int KSM_UNSHARED = 2;
16012 private static final int KSM_VOLATILE = 3;
16014 private final long[] getKsmInfo() {
16015 long[] longOut = new long[4];
16016 final int[] SINGLE_LONG_FORMAT = new int[] {
16017 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16019 long[] longTmp = new long[1];
16020 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16021 SINGLE_LONG_FORMAT, null, longTmp, null);
16022 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16024 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16025 SINGLE_LONG_FORMAT, null, longTmp, null);
16026 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16028 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16029 SINGLE_LONG_FORMAT, null, longTmp, null);
16030 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16032 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16033 SINGLE_LONG_FORMAT, null, longTmp, null);
16034 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16038 private static String stringifySize(long size, int order) {
16039 Locale locale = Locale.US;
16042 return String.format(locale, "%,13d", size);
16044 return String.format(locale, "%,9dK", size / 1024);
16046 return String.format(locale, "%,5dM", size / 1024 / 1024);
16047 case 1024 * 1024 * 1024:
16048 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16050 throw new IllegalArgumentException("Invalid size order");
16054 private static String stringifyKBSize(long size) {
16055 return stringifySize(size * 1024, 1024);
16058 // Update this version number in case you change the 'compact' format
16059 private static final int MEMINFO_COMPACT_VERSION = 1;
16061 final void dumpApplicationMemoryUsage(FileDescriptor fd,
16062 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16063 boolean dumpDetails = false;
16064 boolean dumpFullDetails = false;
16065 boolean dumpDalvik = false;
16066 boolean dumpSummaryOnly = false;
16067 boolean dumpUnreachable = false;
16068 boolean oomOnly = false;
16069 boolean isCompact = false;
16070 boolean localOnly = false;
16071 boolean packages = false;
16072 boolean isCheckinRequest = false;
16073 boolean dumpSwapPss = false;
16076 while (opti < args.length) {
16077 String opt = args[opti];
16078 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16082 if ("-a".equals(opt)) {
16083 dumpDetails = true;
16084 dumpFullDetails = true;
16086 dumpSwapPss = true;
16087 } else if ("-d".equals(opt)) {
16089 } else if ("-c".equals(opt)) {
16091 } else if ("-s".equals(opt)) {
16092 dumpDetails = true;
16093 dumpSummaryOnly = true;
16094 } else if ("-S".equals(opt)) {
16095 dumpSwapPss = true;
16096 } else if ("--unreachable".equals(opt)) {
16097 dumpUnreachable = true;
16098 } else if ("--oom".equals(opt)) {
16100 } else if ("--local".equals(opt)) {
16102 } else if ("--package".equals(opt)) {
16104 } else if ("--checkin".equals(opt)) {
16105 isCheckinRequest = true;
16107 } else if ("-h".equals(opt)) {
16108 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16109 pw.println(" -a: include all available information for each process.");
16110 pw.println(" -d: include dalvik details.");
16111 pw.println(" -c: dump in a compact machine-parseable representation.");
16112 pw.println(" -s: dump only summary of application memory usage.");
16113 pw.println(" -S: dump also SwapPss.");
16114 pw.println(" --oom: only show processes organized by oom adj.");
16115 pw.println(" --local: only collect details locally, don't call process.");
16116 pw.println(" --package: interpret process arg as package, dumping all");
16117 pw.println(" processes that have loaded that package.");
16118 pw.println(" --checkin: dump data for a checkin");
16119 pw.println("If [process] is specified it can be the name or ");
16120 pw.println("pid of a specific process to dump.");
16123 pw.println("Unknown argument: " + opt + "; use -h for help");
16127 long uptime = SystemClock.uptimeMillis();
16128 long realtime = SystemClock.elapsedRealtime();
16129 final long[] tmpLong = new long[1];
16131 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16132 if (procs == null) {
16133 // No Java processes. Maybe they want to print a native process.
16134 if (args != null && args.length > opti
16135 && args[opti].charAt(0) != '-') {
16136 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16137 = new ArrayList<ProcessCpuTracker.Stats>();
16138 updateCpuStatsNow();
16141 findPid = Integer.parseInt(args[opti]);
16142 } catch (NumberFormatException e) {
16144 synchronized (mProcessCpuTracker) {
16145 final int N = mProcessCpuTracker.countStats();
16146 for (int i=0; i<N; i++) {
16147 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16148 if (st.pid == findPid || (st.baseName != null
16149 && st.baseName.equals(args[opti]))) {
16150 nativeProcs.add(st);
16154 if (nativeProcs.size() > 0) {
16155 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16157 Debug.MemoryInfo mi = null;
16158 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16159 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16160 final int pid = r.pid;
16161 if (!isCheckinRequest && dumpDetails) {
16162 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16165 mi = new Debug.MemoryInfo();
16167 if (dumpDetails || (!brief && !oomOnly)) {
16168 Debug.getMemoryInfo(pid, mi);
16170 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16171 mi.dalvikPrivateDirty = (int)tmpLong[0];
16173 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16174 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16175 if (isCheckinRequest) {
16182 pw.println("No process found for: " + args[opti]);
16186 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16187 dumpDetails = true;
16190 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16192 String[] innerArgs = new String[args.length-opti];
16193 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16195 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16196 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16197 long nativePss = 0;
16198 long nativeSwapPss = 0;
16199 long dalvikPss = 0;
16200 long dalvikSwapPss = 0;
16201 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16203 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16206 long otherSwapPss = 0;
16207 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16208 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16210 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16211 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16212 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16213 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16216 long totalSwapPss = 0;
16217 long cachedPss = 0;
16218 long cachedSwapPss = 0;
16219 boolean hasSwapPss = false;
16221 Debug.MemoryInfo mi = null;
16222 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16223 final ProcessRecord r = procs.get(i);
16224 final IApplicationThread thread;
16227 final boolean hasActivities;
16228 synchronized (this) {
16231 oomAdj = r.getSetAdjWithServices();
16232 hasActivities = r.activities.size() > 0;
16234 if (thread != null) {
16235 if (!isCheckinRequest && dumpDetails) {
16236 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16239 mi = new Debug.MemoryInfo();
16241 if (dumpDetails || (!brief && !oomOnly)) {
16242 Debug.getMemoryInfo(pid, mi);
16243 hasSwapPss = mi.hasSwappedOutPss;
16245 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16246 mi.dalvikPrivateDirty = (int)tmpLong[0];
16250 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16251 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16252 if (isCheckinRequest) {
16258 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16259 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16260 } catch (RemoteException e) {
16261 if (!isCheckinRequest) {
16262 pw.println("Got RemoteException!");
16269 final long myTotalPss = mi.getTotalPss();
16270 final long myTotalUss = mi.getTotalUss();
16271 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16273 synchronized (this) {
16274 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16275 // Record this for posterity if the process has been stable.
16276 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16280 if (!isCheckinRequest && mi != null) {
16281 totalPss += myTotalPss;
16282 totalSwapPss += myTotalSwapPss;
16283 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16284 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16285 myTotalSwapPss, pid, hasActivities);
16286 procMems.add(pssItem);
16287 procMemsMap.put(pid, pssItem);
16289 nativePss += mi.nativePss;
16290 nativeSwapPss += mi.nativeSwappedOutPss;
16291 dalvikPss += mi.dalvikPss;
16292 dalvikSwapPss += mi.dalvikSwappedOutPss;
16293 for (int j=0; j<dalvikSubitemPss.length; j++) {
16294 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16295 dalvikSubitemSwapPss[j] +=
16296 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16298 otherPss += mi.otherPss;
16299 otherSwapPss += mi.otherSwappedOutPss;
16300 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16301 long mem = mi.getOtherPss(j);
16304 mem = mi.getOtherSwappedOutPss(j);
16305 miscSwapPss[j] += mem;
16306 otherSwapPss -= mem;
16309 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16310 cachedPss += myTotalPss;
16311 cachedSwapPss += myTotalSwapPss;
16314 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16315 if (oomIndex == (oomPss.length - 1)
16316 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16317 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16318 oomPss[oomIndex] += myTotalPss;
16319 oomSwapPss[oomIndex] += myTotalSwapPss;
16320 if (oomProcs[oomIndex] == null) {
16321 oomProcs[oomIndex] = new ArrayList<MemItem>();
16323 oomProcs[oomIndex].add(pssItem);
16331 long nativeProcTotalPss = 0;
16333 if (!isCheckinRequest && procs.size() > 1 && !packages) {
16334 // If we are showing aggregations, also look for native processes to
16335 // include so that our aggregations are more accurate.
16336 updateCpuStatsNow();
16338 synchronized (mProcessCpuTracker) {
16339 final int N = mProcessCpuTracker.countStats();
16340 for (int i=0; i<N; i++) {
16341 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16342 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16344 mi = new Debug.MemoryInfo();
16346 if (!brief && !oomOnly) {
16347 Debug.getMemoryInfo(st.pid, mi);
16349 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16350 mi.nativePrivateDirty = (int)tmpLong[0];
16353 final long myTotalPss = mi.getTotalPss();
16354 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16355 totalPss += myTotalPss;
16356 nativeProcTotalPss += myTotalPss;
16358 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16359 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16360 procMems.add(pssItem);
16362 nativePss += mi.nativePss;
16363 nativeSwapPss += mi.nativeSwappedOutPss;
16364 dalvikPss += mi.dalvikPss;
16365 dalvikSwapPss += mi.dalvikSwappedOutPss;
16366 for (int j=0; j<dalvikSubitemPss.length; j++) {
16367 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16368 dalvikSubitemSwapPss[j] +=
16369 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16371 otherPss += mi.otherPss;
16372 otherSwapPss += mi.otherSwappedOutPss;
16373 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16374 long mem = mi.getOtherPss(j);
16377 mem = mi.getOtherSwappedOutPss(j);
16378 miscSwapPss[j] += mem;
16379 otherSwapPss -= mem;
16381 oomPss[0] += myTotalPss;
16382 oomSwapPss[0] += myTotalSwapPss;
16383 if (oomProcs[0] == null) {
16384 oomProcs[0] = new ArrayList<MemItem>();
16386 oomProcs[0].add(pssItem);
16391 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16393 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16394 final MemItem dalvikItem =
16395 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16396 if (dalvikSubitemPss.length > 0) {
16397 dalvikItem.subitems = new ArrayList<MemItem>();
16398 for (int j=0; j<dalvikSubitemPss.length; j++) {
16399 final String name = Debug.MemoryInfo.getOtherLabel(
16400 Debug.MemoryInfo.NUM_OTHER_STATS + j);
16401 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16402 dalvikSubitemSwapPss[j], j));
16405 catMems.add(dalvikItem);
16406 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16407 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16408 String label = Debug.MemoryInfo.getOtherLabel(j);
16409 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16412 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16413 for (int j=0; j<oomPss.length; j++) {
16414 if (oomPss[j] != 0) {
16415 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16416 : DUMP_MEM_OOM_LABEL[j];
16417 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16418 DUMP_MEM_OOM_ADJ[j]);
16419 item.subitems = oomProcs[j];
16424 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16425 if (!brief && !oomOnly && !isCompact) {
16427 pw.println("Total PSS by process:");
16428 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
16432 pw.println("Total PSS by OOM adjustment:");
16434 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
16435 if (!brief && !oomOnly) {
16436 PrintWriter out = categoryPw != null ? categoryPw : pw;
16439 out.println("Total PSS by category:");
16441 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
16446 MemInfoReader memInfo = new MemInfoReader();
16447 memInfo.readMemInfo();
16448 if (nativeProcTotalPss > 0) {
16449 synchronized (this) {
16450 final long cachedKb = memInfo.getCachedSizeKb();
16451 final long freeKb = memInfo.getFreeSizeKb();
16452 final long zramKb = memInfo.getZramTotalSizeKb();
16453 final long kernelKb = memInfo.getKernelUsedSizeKb();
16454 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16455 kernelKb*1024, nativeProcTotalPss*1024);
16456 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16457 nativeProcTotalPss);
16462 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16463 pw.print(" (status ");
16464 switch (mLastMemoryLevel) {
16465 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16466 pw.println("normal)");
16468 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16469 pw.println("moderate)");
16471 case ProcessStats.ADJ_MEM_FACTOR_LOW:
16472 pw.println("low)");
16474 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16475 pw.println("critical)");
16478 pw.print(mLastMemoryLevel);
16482 pw.print(" Free RAM: ");
16483 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16484 + memInfo.getFreeSizeKb()));
16486 pw.print(stringifyKBSize(cachedPss));
16487 pw.print(" cached pss + ");
16488 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16489 pw.print(" cached kernel + ");
16490 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16491 pw.println(" free)");
16493 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16494 pw.print(cachedPss + memInfo.getCachedSizeKb()
16495 + memInfo.getFreeSizeKb()); pw.print(",");
16496 pw.println(totalPss - cachedPss);
16499 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16500 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16501 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16503 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16504 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16505 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16506 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16507 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16509 pw.print("lostram,"); pw.println(lostRAM);
16512 if (memInfo.getZramTotalSizeKb() != 0) {
16514 pw.print(" ZRAM: ");
16515 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16516 pw.print(" physical used for ");
16517 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16518 - memInfo.getSwapFreeSizeKb()));
16519 pw.print(" in swap (");
16520 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16521 pw.println(" total swap)");
16523 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16524 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16525 pw.println(memInfo.getSwapFreeSizeKb());
16528 final long[] ksm = getKsmInfo();
16530 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16531 || ksm[KSM_VOLATILE] != 0) {
16532 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16533 pw.print(" saved from shared ");
16534 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16535 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16536 pw.print(" unshared; ");
16537 pw.print(stringifyKBSize(
16538 ksm[KSM_VOLATILE])); pw.println(" volatile");
16540 pw.print(" Tuning: ");
16541 pw.print(ActivityManager.staticGetMemoryClass());
16542 pw.print(" (large ");
16543 pw.print(ActivityManager.staticGetLargeMemoryClass());
16544 pw.print("), oom ");
16545 pw.print(stringifySize(
16546 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16547 pw.print(", restore limit ");
16548 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16549 if (ActivityManager.isLowRamDeviceStatic()) {
16550 pw.print(" (low-ram)");
16552 if (ActivityManager.isHighEndGfx()) {
16553 pw.print(" (high-end-gfx)");
16557 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16558 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16559 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16560 pw.print("tuning,");
16561 pw.print(ActivityManager.staticGetMemoryClass());
16563 pw.print(ActivityManager.staticGetLargeMemoryClass());
16565 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16566 if (ActivityManager.isLowRamDeviceStatic()) {
16567 pw.print(",low-ram");
16569 if (ActivityManager.isHighEndGfx()) {
16570 pw.print(",high-end-gfx");
16578 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16579 long memtrack, String name) {
16581 sb.append(ProcessList.makeOomAdjString(oomAdj));
16583 sb.append(ProcessList.makeProcStateString(procState));
16585 ProcessList.appendRamKb(sb, pss);
16588 if (memtrack > 0) {
16590 sb.append(stringifyKBSize(memtrack));
16591 sb.append(" memtrack)");
16595 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16596 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16597 sb.append(" (pid ");
16600 sb.append(mi.adjType);
16602 if (mi.adjReason != null) {
16604 sb.append(mi.adjReason);
16609 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16610 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16611 for (int i=0, N=memInfos.size(); i<N; i++) {
16612 ProcessMemInfo mi = memInfos.get(i);
16613 infoMap.put(mi.pid, mi);
16615 updateCpuStatsNow();
16616 long[] memtrackTmp = new long[1];
16617 final List<ProcessCpuTracker.Stats> stats;
16618 // Get a list of Stats that have vsize > 0
16619 synchronized (mProcessCpuTracker) {
16620 stats = mProcessCpuTracker.getStats((st) -> {
16621 return st.vsize > 0;
16624 final int statsCount = stats.size();
16625 for (int i = 0; i < statsCount; i++) {
16626 ProcessCpuTracker.Stats st = stats.get(i);
16627 long pss = Debug.getPss(st.pid, null, memtrackTmp);
16629 if (infoMap.indexOfKey(st.pid) < 0) {
16630 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16631 ProcessList.NATIVE_ADJ, -1, "native", null);
16633 mi.memtrack = memtrackTmp[0];
16640 long totalMemtrack = 0;
16641 for (int i=0, N=memInfos.size(); i<N; i++) {
16642 ProcessMemInfo mi = memInfos.get(i);
16644 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16645 mi.memtrack = memtrackTmp[0];
16647 totalPss += mi.pss;
16648 totalMemtrack += mi.memtrack;
16650 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16651 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16652 if (lhs.oomAdj != rhs.oomAdj) {
16653 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16655 if (lhs.pss != rhs.pss) {
16656 return lhs.pss < rhs.pss ? 1 : -1;
16662 StringBuilder tag = new StringBuilder(128);
16663 StringBuilder stack = new StringBuilder(128);
16664 tag.append("Low on memory -- ");
16665 appendMemBucket(tag, totalPss, "total", false);
16666 appendMemBucket(stack, totalPss, "total", true);
16668 StringBuilder fullNativeBuilder = new StringBuilder(1024);
16669 StringBuilder shortNativeBuilder = new StringBuilder(1024);
16670 StringBuilder fullJavaBuilder = new StringBuilder(1024);
16672 boolean firstLine = true;
16673 int lastOomAdj = Integer.MIN_VALUE;
16674 long extraNativeRam = 0;
16675 long extraNativeMemtrack = 0;
16676 long cachedPss = 0;
16677 for (int i=0, N=memInfos.size(); i<N; i++) {
16678 ProcessMemInfo mi = memInfos.get(i);
16680 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16681 cachedPss += mi.pss;
16684 if (mi.oomAdj != ProcessList.NATIVE_ADJ
16685 && (mi.oomAdj < ProcessList.SERVICE_ADJ
16686 || mi.oomAdj == ProcessList.HOME_APP_ADJ
16687 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16688 if (lastOomAdj != mi.oomAdj) {
16689 lastOomAdj = mi.oomAdj;
16690 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16693 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16698 stack.append("\n\t at ");
16706 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16707 appendMemBucket(tag, mi.pss, mi.name, false);
16709 appendMemBucket(stack, mi.pss, mi.name, true);
16710 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16711 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16713 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16714 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16715 stack.append(DUMP_MEM_OOM_LABEL[k]);
16717 stack.append(DUMP_MEM_OOM_ADJ[k]);
16724 appendMemInfo(fullNativeBuilder, mi);
16725 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16726 // The short form only has native processes that are >= 512K.
16727 if (mi.pss >= 512) {
16728 appendMemInfo(shortNativeBuilder, mi);
16730 extraNativeRam += mi.pss;
16731 extraNativeMemtrack += mi.memtrack;
16734 // Short form has all other details, but if we have collected RAM
16735 // from smaller native processes let's dump a summary of that.
16736 if (extraNativeRam > 0) {
16737 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16738 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16739 shortNativeBuilder.append('\n');
16740 extraNativeRam = 0;
16742 appendMemInfo(fullJavaBuilder, mi);
16746 fullJavaBuilder.append(" ");
16747 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16748 fullJavaBuilder.append(": TOTAL");
16749 if (totalMemtrack > 0) {
16750 fullJavaBuilder.append(" (");
16751 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16752 fullJavaBuilder.append(" memtrack)");
16755 fullJavaBuilder.append("\n");
16757 MemInfoReader memInfo = new MemInfoReader();
16758 memInfo.readMemInfo();
16759 final long[] infos = memInfo.getRawInfo();
16761 StringBuilder memInfoBuilder = new StringBuilder(1024);
16762 Debug.getMemInfo(infos);
16763 memInfoBuilder.append(" MemInfo: ");
16764 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16765 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16766 memInfoBuilder.append(stringifyKBSize(
16767 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16768 memInfoBuilder.append(stringifyKBSize(
16769 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16770 memInfoBuilder.append(stringifyKBSize(
16771 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16772 memInfoBuilder.append(" ");
16773 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16774 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16775 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16776 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16777 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16778 memInfoBuilder.append(" ZRAM: ");
16779 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16780 memInfoBuilder.append(" RAM, ");
16781 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16782 memInfoBuilder.append(" swap total, ");
16783 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16784 memInfoBuilder.append(" swap free\n");
16786 final long[] ksm = getKsmInfo();
16787 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16788 || ksm[KSM_VOLATILE] != 0) {
16789 memInfoBuilder.append(" KSM: ");
16790 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16791 memInfoBuilder.append(" saved from shared ");
16792 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16793 memInfoBuilder.append("\n ");
16794 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16795 memInfoBuilder.append(" unshared; ");
16796 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16797 memInfoBuilder.append(" volatile\n");
16799 memInfoBuilder.append(" Free RAM: ");
16800 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16801 + memInfo.getFreeSizeKb()));
16802 memInfoBuilder.append("\n");
16803 memInfoBuilder.append(" Used RAM: ");
16804 memInfoBuilder.append(stringifyKBSize(
16805 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16806 memInfoBuilder.append("\n");
16807 memInfoBuilder.append(" Lost RAM: ");
16808 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16809 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16810 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16811 memInfoBuilder.append("\n");
16812 Slog.i(TAG, "Low on memory:");
16813 Slog.i(TAG, shortNativeBuilder.toString());
16814 Slog.i(TAG, fullJavaBuilder.toString());
16815 Slog.i(TAG, memInfoBuilder.toString());
16817 StringBuilder dropBuilder = new StringBuilder(1024);
16819 StringWriter oomSw = new StringWriter();
16820 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16821 StringWriter catSw = new StringWriter();
16822 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16823 String[] emptyArgs = new String[] { };
16824 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16826 String oomString = oomSw.toString();
16828 dropBuilder.append("Low on memory:");
16829 dropBuilder.append(stack);
16830 dropBuilder.append('\n');
16831 dropBuilder.append(fullNativeBuilder);
16832 dropBuilder.append(fullJavaBuilder);
16833 dropBuilder.append('\n');
16834 dropBuilder.append(memInfoBuilder);
16835 dropBuilder.append('\n');
16837 dropBuilder.append(oomString);
16838 dropBuilder.append('\n');
16840 StringWriter catSw = new StringWriter();
16841 synchronized (ActivityManagerService.this) {
16842 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16843 String[] emptyArgs = new String[] { };
16845 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16847 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16848 false, null).dumpLocked();
16850 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16853 dropBuilder.append(catSw.toString());
16854 addErrorToDropBox("lowmem", null, "system_server", null,
16855 null, tag.toString(), dropBuilder.toString(), null, null);
16856 //Slog.i(TAG, "Sent to dropbox:");
16857 //Slog.i(TAG, dropBuilder.toString());
16858 synchronized (ActivityManagerService.this) {
16859 long now = SystemClock.uptimeMillis();
16860 if (mLastMemUsageReportTime < now) {
16861 mLastMemUsageReportTime = now;
16867 * Searches array of arguments for the specified string
16868 * @param args array of argument strings
16869 * @param value value to search for
16870 * @return true if the value is contained in the array
16872 private static boolean scanArgs(String[] args, String value) {
16873 if (args != null) {
16874 for (String arg : args) {
16875 if (value.equals(arg)) {
16883 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16884 ContentProviderRecord cpr, boolean always) {
16885 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16887 if (!inLaunching || always) {
16888 synchronized (cpr) {
16889 cpr.launchingApp = null;
16892 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16893 String names[] = cpr.info.authority.split(";");
16894 for (int j = 0; j < names.length; j++) {
16895 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16899 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16900 ContentProviderConnection conn = cpr.connections.get(i);
16901 if (conn.waiting) {
16902 // If this connection is waiting for the provider, then we don't
16903 // need to mess with its process unless we are always removing
16904 // or for some reason the provider is not currently launching.
16905 if (inLaunching && !always) {
16909 ProcessRecord capp = conn.client;
16911 if (conn.stableCount > 0) {
16912 if (!capp.persistent && capp.thread != null
16914 && capp.pid != MY_PID) {
16915 capp.kill("depends on provider "
16916 + cpr.name.flattenToShortString()
16917 + " in dying proc " + (proc != null ? proc.processName : "??")
16918 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16920 } else if (capp.thread != null && conn.provider.provider != null) {
16922 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16923 } catch (RemoteException e) {
16925 // In the protocol here, we don't expect the client to correctly
16926 // clean up this connection, we'll just remove it.
16927 cpr.connections.remove(i);
16928 if (conn.client.conProviders.remove(conn)) {
16929 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16934 if (inLaunching && always) {
16935 mLaunchingProviders.remove(cpr);
16937 return inLaunching;
16941 * Main code for cleaning up a process when it has gone away. This is
16942 * called both as a result of the process dying, or directly when stopping
16943 * a process when running in single process mode.
16945 * @return Returns true if the given process has been restarted, so the
16946 * app that was passed in must remain on the process lists.
16948 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16949 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16950 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16952 removeLruProcessLocked(app);
16953 ProcessList.remove(app.pid);
16956 mProcessesToGc.remove(app);
16957 mPendingPssProcesses.remove(app);
16959 // Dismiss any open dialogs.
16960 if (app.crashDialog != null && !app.forceCrashReport) {
16961 app.crashDialog.dismiss();
16962 app.crashDialog = null;
16964 if (app.anrDialog != null) {
16965 app.anrDialog.dismiss();
16966 app.anrDialog = null;
16968 if (app.waitDialog != null) {
16969 app.waitDialog.dismiss();
16970 app.waitDialog = null;
16973 app.crashing = false;
16974 app.notResponding = false;
16976 app.resetPackageList(mProcessStats);
16977 app.unlinkDeathRecipient();
16978 app.makeInactive(mProcessStats);
16979 app.waitingToKill = null;
16980 app.forcingToForeground = null;
16981 updateProcessForegroundLocked(app, false, false);
16982 app.foregroundActivities = false;
16983 app.hasShownUi = false;
16984 app.treatLikeActivity = false;
16985 app.hasAboveClient = false;
16986 app.hasClientActivities = false;
16988 mServices.killServicesLocked(app, allowRestart);
16990 boolean restart = false;
16992 // Remove published content providers.
16993 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16994 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16995 final boolean always = app.bad || !allowRestart;
16996 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16997 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16998 // We left the provider in the launching list, need to
17003 cpr.provider = null;
17006 app.pubProviders.clear();
17008 // Take care of any launching providers waiting for this process.
17009 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17013 // Unregister from connected content providers.
17014 if (!app.conProviders.isEmpty()) {
17015 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17016 ContentProviderConnection conn = app.conProviders.get(i);
17017 conn.provider.connections.remove(conn);
17018 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17019 conn.provider.name);
17021 app.conProviders.clear();
17024 // At this point there may be remaining entries in mLaunchingProviders
17025 // where we were the only one waiting, so they are no longer of use.
17026 // Look for these and clean up if found.
17027 // XXX Commented out for now. Trying to figure out a way to reproduce
17028 // the actual situation to identify what is actually going on.
17030 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17031 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17032 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17033 synchronized (cpr) {
17034 cpr.launchingApp = null;
17041 skipCurrentReceiverLocked(app);
17043 // Unregister any receivers.
17044 for (int i = app.receivers.size() - 1; i >= 0; i--) {
17045 removeReceiverLocked(app.receivers.valueAt(i));
17047 app.receivers.clear();
17049 // If the app is undergoing backup, tell the backup manager about it
17050 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17051 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17052 + mBackupTarget.appInfo + " died during backup");
17054 IBackupManager bm = IBackupManager.Stub.asInterface(
17055 ServiceManager.getService(Context.BACKUP_SERVICE));
17056 bm.agentDisconnected(app.info.packageName);
17057 } catch (RemoteException e) {
17058 // can't happen; backup manager is local
17062 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17063 ProcessChangeItem item = mPendingProcessChanges.get(i);
17064 if (item.pid == app.pid) {
17065 mPendingProcessChanges.remove(i);
17066 mAvailProcessChanges.add(item);
17069 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17070 null).sendToTarget();
17072 // If the caller is restarting this app, then leave it in its
17073 // current lists and let the caller take care of it.
17078 if (!app.persistent || app.isolated) {
17079 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17080 "Removing non-persistent process during cleanup: " + app);
17081 if (!replacingPid) {
17082 removeProcessNameLocked(app.processName, app.uid, app);
17084 if (mHeavyWeightProcess == app) {
17085 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17086 mHeavyWeightProcess.userId, 0));
17087 mHeavyWeightProcess = null;
17089 } else if (!app.removed) {
17090 // This app is persistent, so we need to keep its record around.
17091 // If it is not already on the pending app list, add it there
17092 // and start a new process for it.
17093 if (mPersistentStartingProcesses.indexOf(app) < 0) {
17094 mPersistentStartingProcesses.add(app);
17098 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17099 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17100 mProcessesOnHold.remove(app);
17102 if (app == mHomeProcess) {
17103 mHomeProcess = null;
17105 if (app == mPreviousProcess) {
17106 mPreviousProcess = null;
17109 if (restart && !app.isolated) {
17110 // We have components that still need to be running in the
17111 // process, so re-launch it.
17113 ProcessList.remove(app.pid);
17115 addProcessNameLocked(app);
17116 startProcessLocked(app, "restart", app.processName);
17118 } else if (app.pid > 0 && app.pid != MY_PID) {
17121 synchronized (mPidsSelfLocked) {
17122 mPidsSelfLocked.remove(app.pid);
17123 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17125 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17126 if (app.isolated) {
17127 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17134 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17135 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17136 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17137 if (cpr.launchingApp == app) {
17144 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17145 // Look through the content providers we are waiting to have launched,
17146 // and if any run in this process then either schedule a restart of
17147 // the process or kill the client waiting for it if this process has
17149 boolean restart = false;
17150 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17151 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17152 if (cpr.launchingApp == app) {
17153 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17156 removeDyingProviderLocked(app, cpr, true);
17163 // =========================================================
17165 // =========================================================
17168 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17170 enforceNotIsolatedCaller("getServices");
17171 synchronized (this) {
17172 return mServices.getRunningServiceInfoLocked(maxNum, flags);
17177 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17178 enforceNotIsolatedCaller("getRunningServiceControlPanel");
17179 synchronized (this) {
17180 return mServices.getRunningServiceControlPanelLocked(name);
17185 public ComponentName startService(IApplicationThread caller, Intent service,
17186 String resolvedType, String callingPackage, int userId)
17187 throws TransactionTooLargeException {
17188 enforceNotIsolatedCaller("startService");
17189 // Refuse possible leaked file descriptors
17190 if (service != null && service.hasFileDescriptors() == true) {
17191 throw new IllegalArgumentException("File descriptors passed in Intent");
17194 if (callingPackage == null) {
17195 throw new IllegalArgumentException("callingPackage cannot be null");
17198 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17199 "startService: " + service + " type=" + resolvedType);
17200 synchronized(this) {
17201 final int callingPid = Binder.getCallingPid();
17202 final int callingUid = Binder.getCallingUid();
17203 final long origId = Binder.clearCallingIdentity();
17204 ComponentName res = mServices.startServiceLocked(caller, service,
17205 resolvedType, callingPid, callingUid, callingPackage, userId);
17206 Binder.restoreCallingIdentity(origId);
17211 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17212 String callingPackage, int userId)
17213 throws TransactionTooLargeException {
17214 synchronized(this) {
17215 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17216 "startServiceInPackage: " + service + " type=" + resolvedType);
17217 final long origId = Binder.clearCallingIdentity();
17218 ComponentName res = mServices.startServiceLocked(null, service,
17219 resolvedType, -1, uid, callingPackage, userId);
17220 Binder.restoreCallingIdentity(origId);
17226 public int stopService(IApplicationThread caller, Intent service,
17227 String resolvedType, int userId) {
17228 enforceNotIsolatedCaller("stopService");
17229 // Refuse possible leaked file descriptors
17230 if (service != null && service.hasFileDescriptors() == true) {
17231 throw new IllegalArgumentException("File descriptors passed in Intent");
17234 synchronized(this) {
17235 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17240 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17241 enforceNotIsolatedCaller("peekService");
17242 // Refuse possible leaked file descriptors
17243 if (service != null && service.hasFileDescriptors() == true) {
17244 throw new IllegalArgumentException("File descriptors passed in Intent");
17247 if (callingPackage == null) {
17248 throw new IllegalArgumentException("callingPackage cannot be null");
17251 synchronized(this) {
17252 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17257 public boolean stopServiceToken(ComponentName className, IBinder token,
17259 synchronized(this) {
17260 return mServices.stopServiceTokenLocked(className, token, startId);
17265 public void setServiceForeground(ComponentName className, IBinder token,
17266 int id, Notification notification, int flags) {
17267 synchronized(this) {
17268 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17273 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17274 boolean requireFull, String name, String callerPackage) {
17275 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17276 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17279 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17280 String className, int flags) {
17281 boolean result = false;
17282 // For apps that don't have pre-defined UIDs, check for permission
17283 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17284 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17285 if (ActivityManager.checkUidPermission(
17286 INTERACT_ACROSS_USERS,
17287 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17288 ComponentName comp = new ComponentName(aInfo.packageName, className);
17289 String msg = "Permission Denial: Component " + comp.flattenToShortString()
17290 + " requests FLAG_SINGLE_USER, but app does not hold "
17291 + INTERACT_ACROSS_USERS;
17293 throw new SecurityException(msg);
17295 // Permission passed
17298 } else if ("system".equals(componentProcessName)) {
17300 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17301 // Phone app and persistent apps are allowed to export singleuser providers.
17302 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17303 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17305 if (DEBUG_MU) Slog.v(TAG_MU,
17306 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17307 + Integer.toHexString(flags) + ") = " + result);
17312 * Checks to see if the caller is in the same app as the singleton
17313 * component, or the component is in a special app. It allows special apps
17314 * to export singleton components but prevents exporting singleton
17315 * components for regular apps.
17317 boolean isValidSingletonCall(int callingUid, int componentUid) {
17318 int componentAppId = UserHandle.getAppId(componentUid);
17319 return UserHandle.isSameApp(callingUid, componentUid)
17320 || componentAppId == Process.SYSTEM_UID
17321 || componentAppId == Process.PHONE_UID
17322 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17323 == PackageManager.PERMISSION_GRANTED;
17326 public int bindService(IApplicationThread caller, IBinder token, Intent service,
17327 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17328 int userId) throws TransactionTooLargeException {
17329 enforceNotIsolatedCaller("bindService");
17331 // Refuse possible leaked file descriptors
17332 if (service != null && service.hasFileDescriptors() == true) {
17333 throw new IllegalArgumentException("File descriptors passed in Intent");
17336 if (callingPackage == null) {
17337 throw new IllegalArgumentException("callingPackage cannot be null");
17340 synchronized(this) {
17341 return mServices.bindServiceLocked(caller, token, service,
17342 resolvedType, connection, flags, callingPackage, userId);
17346 public boolean unbindService(IServiceConnection connection) {
17347 synchronized (this) {
17348 return mServices.unbindServiceLocked(connection);
17352 public void publishService(IBinder token, Intent intent, IBinder service) {
17353 // Refuse possible leaked file descriptors
17354 if (intent != null && intent.hasFileDescriptors() == true) {
17355 throw new IllegalArgumentException("File descriptors passed in Intent");
17358 synchronized(this) {
17359 if (!(token instanceof ServiceRecord)) {
17360 throw new IllegalArgumentException("Invalid service token");
17362 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17366 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17367 // Refuse possible leaked file descriptors
17368 if (intent != null && intent.hasFileDescriptors() == true) {
17369 throw new IllegalArgumentException("File descriptors passed in Intent");
17372 synchronized(this) {
17373 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17377 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17378 synchronized(this) {
17379 if (!(token instanceof ServiceRecord)) {
17380 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17381 throw new IllegalArgumentException("Invalid service token");
17383 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17387 // =========================================================
17388 // BACKUP AND RESTORE
17389 // =========================================================
17391 // Cause the target app to be launched if necessary and its backup agent
17392 // instantiated. The backup agent will invoke backupAgentCreated() on the
17393 // activity manager to announce its creation.
17394 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17395 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17396 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17398 IPackageManager pm = AppGlobals.getPackageManager();
17399 ApplicationInfo app = null;
17401 app = pm.getApplicationInfo(packageName, 0, userId);
17402 } catch (RemoteException e) {
17403 // can't happen; package manager is process-local
17406 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17410 synchronized(this) {
17411 // !!! TODO: currently no check here that we're already bound
17412 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17413 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17414 synchronized (stats) {
17415 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17418 // Backup agent is now in use, its package can't be stopped.
17420 AppGlobals.getPackageManager().setPackageStoppedState(
17421 app.packageName, false, UserHandle.getUserId(app.uid));
17422 } catch (RemoteException e) {
17423 } catch (IllegalArgumentException e) {
17424 Slog.w(TAG, "Failed trying to unstop package "
17425 + app.packageName + ": " + e);
17428 BackupRecord r = new BackupRecord(ss, app, backupMode);
17429 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17430 ? new ComponentName(app.packageName, app.backupAgentName)
17431 : new ComponentName("android", "FullBackupAgent");
17432 // startProcessLocked() returns existing proc's record if it's already running
17433 ProcessRecord proc = startProcessLocked(app.processName, app,
17434 false, 0, "backup", hostingName, false, false, false);
17435 if (proc == null) {
17436 Slog.e(TAG, "Unable to start backup agent process " + r);
17440 // If the app is a regular app (uid >= 10000) and not the system server or phone
17441 // process, etc, then mark it as being in full backup so that certain calls to the
17442 // process can be blocked. This is not reset to false anywhere because we kill the
17443 // process after the full backup is done and the ProcessRecord will vaporize anyway.
17444 if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17445 proc.inFullBackup = true;
17449 mBackupAppName = app.packageName;
17451 // Try not to kill the process during backup
17452 updateOomAdjLocked(proc);
17454 // If the process is already attached, schedule the creation of the backup agent now.
17455 // If it is not yet live, this will be done when it attaches to the framework.
17456 if (proc.thread != null) {
17457 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17459 proc.thread.scheduleCreateBackupAgent(app,
17460 compatibilityInfoForPackageLocked(app), backupMode);
17461 } catch (RemoteException e) {
17462 // Will time out on the backup manager side
17465 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17467 // Invariants: at this point, the target app process exists and the application
17468 // is either already running or in the process of coming up. mBackupTarget and
17469 // mBackupAppName describe the app, so that when it binds back to the AM we
17470 // know that it's scheduled for a backup-agent operation.
17477 public void clearPendingBackup() {
17478 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17479 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17481 synchronized (this) {
17482 mBackupTarget = null;
17483 mBackupAppName = null;
17487 // A backup agent has just come up
17488 public void backupAgentCreated(String agentPackageName, IBinder agent) {
17489 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17492 synchronized(this) {
17493 if (!agentPackageName.equals(mBackupAppName)) {
17494 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17499 long oldIdent = Binder.clearCallingIdentity();
17501 IBackupManager bm = IBackupManager.Stub.asInterface(
17502 ServiceManager.getService(Context.BACKUP_SERVICE));
17503 bm.agentConnected(agentPackageName, agent);
17504 } catch (RemoteException e) {
17505 // can't happen; the backup manager service is local
17506 } catch (Exception e) {
17507 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17508 e.printStackTrace();
17510 Binder.restoreCallingIdentity(oldIdent);
17514 // done with this agent
17515 public void unbindBackupAgent(ApplicationInfo appInfo) {
17516 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17517 if (appInfo == null) {
17518 Slog.w(TAG, "unbind backup agent for null app");
17522 synchronized(this) {
17524 if (mBackupAppName == null) {
17525 Slog.w(TAG, "Unbinding backup agent with no active backup");
17529 if (!mBackupAppName.equals(appInfo.packageName)) {
17530 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17534 // Not backing this app up any more; reset its OOM adjustment
17535 final ProcessRecord proc = mBackupTarget.app;
17536 updateOomAdjLocked(proc);
17538 // If the app crashed during backup, 'thread' will be null here
17539 if (proc.thread != null) {
17541 proc.thread.scheduleDestroyBackupAgent(appInfo,
17542 compatibilityInfoForPackageLocked(appInfo));
17543 } catch (Exception e) {
17544 Slog.e(TAG, "Exception when unbinding backup agent:");
17545 e.printStackTrace();
17549 mBackupTarget = null;
17550 mBackupAppName = null;
17554 // =========================================================
17556 // =========================================================
17558 boolean isPendingBroadcastProcessLocked(int pid) {
17559 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17560 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17563 void skipPendingBroadcastLocked(int pid) {
17564 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17565 for (BroadcastQueue queue : mBroadcastQueues) {
17566 queue.skipPendingBroadcastLocked(pid);
17570 // The app just attached; send any pending broadcasts that it should receive
17571 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17572 boolean didSomething = false;
17573 for (BroadcastQueue queue : mBroadcastQueues) {
17574 didSomething |= queue.sendPendingBroadcastsLocked(app);
17576 return didSomething;
17579 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17580 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17581 enforceNotIsolatedCaller("registerReceiver");
17582 ArrayList<Intent> stickyIntents = null;
17583 ProcessRecord callerApp = null;
17586 synchronized(this) {
17587 if (caller != null) {
17588 callerApp = getRecordForAppLocked(caller);
17589 if (callerApp == null) {
17590 throw new SecurityException(
17591 "Unable to find app for caller " + caller
17592 + " (pid=" + Binder.getCallingPid()
17593 + ") when registering receiver " + receiver);
17595 if (callerApp.info.uid != Process.SYSTEM_UID &&
17596 !callerApp.pkgList.containsKey(callerPackage) &&
17597 !"android".equals(callerPackage)) {
17598 throw new SecurityException("Given caller package " + callerPackage
17599 + " is not running in process " + callerApp);
17601 callingUid = callerApp.info.uid;
17602 callingPid = callerApp.pid;
17604 callerPackage = null;
17605 callingUid = Binder.getCallingUid();
17606 callingPid = Binder.getCallingPid();
17609 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17610 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17612 Iterator<String> actions = filter.actionsIterator();
17613 if (actions == null) {
17614 ArrayList<String> noAction = new ArrayList<String>(1);
17615 noAction.add(null);
17616 actions = noAction.iterator();
17619 // Collect stickies of users
17620 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17621 while (actions.hasNext()) {
17622 String action = actions.next();
17623 for (int id : userIds) {
17624 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17625 if (stickies != null) {
17626 ArrayList<Intent> intents = stickies.get(action);
17627 if (intents != null) {
17628 if (stickyIntents == null) {
17629 stickyIntents = new ArrayList<Intent>();
17631 stickyIntents.addAll(intents);
17638 ArrayList<Intent> allSticky = null;
17639 if (stickyIntents != null) {
17640 final ContentResolver resolver = mContext.getContentResolver();
17641 // Look for any matching sticky broadcasts...
17642 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17643 Intent intent = stickyIntents.get(i);
17644 // If intent has scheme "content", it will need to acccess
17645 // provider that needs to lock mProviderMap in ActivityThread
17646 // and also it may need to wait application response, so we
17647 // cannot lock ActivityManagerService here.
17648 if (filter.match(resolver, intent, true, TAG) >= 0) {
17649 if (allSticky == null) {
17650 allSticky = new ArrayList<Intent>();
17652 allSticky.add(intent);
17657 // The first sticky in the list is returned directly back to the client.
17658 Intent sticky = allSticky != null ? allSticky.get(0) : null;
17659 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17660 if (receiver == null) {
17664 synchronized (this) {
17665 if (callerApp != null && (callerApp.thread == null
17666 || callerApp.thread.asBinder() != caller.asBinder())) {
17667 // Original caller already died
17670 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17672 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17674 if (rl.app != null) {
17675 rl.app.receivers.add(rl);
17678 receiver.asBinder().linkToDeath(rl, 0);
17679 } catch (RemoteException e) {
17682 rl.linkedToDeath = true;
17684 mRegisteredReceivers.put(receiver.asBinder(), rl);
17685 } else if (rl.uid != callingUid) {
17686 throw new IllegalArgumentException(
17687 "Receiver requested to register for uid " + callingUid
17688 + " was previously registered for uid " + rl.uid);
17689 } else if (rl.pid != callingPid) {
17690 throw new IllegalArgumentException(
17691 "Receiver requested to register for pid " + callingPid
17692 + " was previously registered for pid " + rl.pid);
17693 } else if (rl.userId != userId) {
17694 throw new IllegalArgumentException(
17695 "Receiver requested to register for user " + userId
17696 + " was previously registered for user " + rl.userId);
17698 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17699 permission, callingUid, userId);
17701 if (!bf.debugCheck()) {
17702 Slog.w(TAG, "==> For Dynamic broadcast");
17704 mReceiverResolver.addFilter(bf);
17706 // Enqueue broadcasts for all existing stickies that match
17708 if (allSticky != null) {
17709 ArrayList receivers = new ArrayList();
17712 final int stickyCount = allSticky.size();
17713 for (int i = 0; i < stickyCount; i++) {
17714 Intent intent = allSticky.get(i);
17715 BroadcastQueue queue = broadcastQueueForIntent(intent);
17716 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17717 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17718 null, 0, null, null, false, true, true, -1);
17719 queue.enqueueParallelBroadcastLocked(r);
17720 queue.scheduleBroadcastsLocked();
17728 public void unregisterReceiver(IIntentReceiver receiver) {
17729 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17731 final long origId = Binder.clearCallingIdentity();
17733 boolean doTrim = false;
17735 synchronized(this) {
17736 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17738 final BroadcastRecord r = rl.curBroadcast;
17739 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17740 final boolean doNext = r.queue.finishReceiverLocked(
17741 r, r.resultCode, r.resultData, r.resultExtras,
17742 r.resultAbort, false);
17745 r.queue.processNextBroadcast(false);
17749 if (rl.app != null) {
17750 rl.app.receivers.remove(rl);
17752 removeReceiverLocked(rl);
17753 if (rl.linkedToDeath) {
17754 rl.linkedToDeath = false;
17755 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17760 // If we actually concluded any broadcasts, we might now be able
17761 // to trim the recipients' apps from our working set
17763 trimApplications();
17768 Binder.restoreCallingIdentity(origId);
17772 void removeReceiverLocked(ReceiverList rl) {
17773 mRegisteredReceivers.remove(rl.receiver.asBinder());
17774 for (int i = rl.size() - 1; i >= 0; i--) {
17775 mReceiverResolver.removeFilter(rl.get(i));
17779 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17780 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17781 ProcessRecord r = mLruProcesses.get(i);
17782 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17784 r.thread.dispatchPackageBroadcast(cmd, packages);
17785 } catch (RemoteException ex) {
17791 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17792 int callingUid, int[] users) {
17793 // TODO: come back and remove this assumption to triage all broadcasts
17794 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17796 List<ResolveInfo> receivers = null;
17798 HashSet<ComponentName> singleUserReceivers = null;
17799 boolean scannedFirstReceivers = false;
17800 for (int user : users) {
17801 // Skip users that have Shell restrictions, with exception of always permitted
17802 // Shell broadcasts
17803 if (callingUid == Process.SHELL_UID
17804 && mUserController.hasUserRestriction(
17805 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17806 && !isPermittedShellBroadcast(intent)) {
17809 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17810 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17811 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17812 // If this is not the system user, we need to check for
17813 // any receivers that should be filtered out.
17814 for (int i=0; i<newReceivers.size(); i++) {
17815 ResolveInfo ri = newReceivers.get(i);
17816 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17817 newReceivers.remove(i);
17822 if (newReceivers != null && newReceivers.size() == 0) {
17823 newReceivers = null;
17825 if (receivers == null) {
17826 receivers = newReceivers;
17827 } else if (newReceivers != null) {
17828 // We need to concatenate the additional receivers
17829 // found with what we have do far. This would be easy,
17830 // but we also need to de-dup any receivers that are
17832 if (!scannedFirstReceivers) {
17833 // Collect any single user receivers we had already retrieved.
17834 scannedFirstReceivers = true;
17835 for (int i=0; i<receivers.size(); i++) {
17836 ResolveInfo ri = receivers.get(i);
17837 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17838 ComponentName cn = new ComponentName(
17839 ri.activityInfo.packageName, ri.activityInfo.name);
17840 if (singleUserReceivers == null) {
17841 singleUserReceivers = new HashSet<ComponentName>();
17843 singleUserReceivers.add(cn);
17847 // Add the new results to the existing results, tracking
17848 // and de-dupping single user receivers.
17849 for (int i=0; i<newReceivers.size(); i++) {
17850 ResolveInfo ri = newReceivers.get(i);
17851 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17852 ComponentName cn = new ComponentName(
17853 ri.activityInfo.packageName, ri.activityInfo.name);
17854 if (singleUserReceivers == null) {
17855 singleUserReceivers = new HashSet<ComponentName>();
17857 if (!singleUserReceivers.contains(cn)) {
17858 singleUserReceivers.add(cn);
17867 } catch (RemoteException ex) {
17868 // pm is in same process, this will never happen.
17873 private boolean isPermittedShellBroadcast(Intent intent) {
17874 // remote bugreport should always be allowed to be taken
17875 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17878 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17879 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17880 final String action = intent.getAction();
17881 if (isProtectedBroadcast
17882 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17883 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17884 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17885 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17886 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17887 || Intent.ACTION_MASTER_CLEAR.equals(action)
17888 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17889 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17890 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17891 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17892 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17893 // Broadcast is either protected, or it's a public action that
17894 // we've relaxed, so it's fine for system internals to send.
17898 // This broadcast may be a problem... but there are often system components that
17899 // want to send an internal broadcast to themselves, which is annoying to have to
17900 // explicitly list each action as a protected broadcast, so we will check for that
17901 // one safe case and allow it: an explicit broadcast, only being received by something
17902 // that has protected itself.
17903 if (receivers != null && receivers.size() > 0
17904 && (intent.getPackage() != null || intent.getComponent() != null)) {
17905 boolean allProtected = true;
17906 for (int i = receivers.size()-1; i >= 0; i--) {
17907 Object target = receivers.get(i);
17908 if (target instanceof ResolveInfo) {
17909 ResolveInfo ri = (ResolveInfo)target;
17910 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17911 allProtected = false;
17915 BroadcastFilter bf = (BroadcastFilter)target;
17916 if (bf.requiredPermission == null) {
17917 allProtected = false;
17922 if (allProtected) {
17928 // The vast majority of broadcasts sent from system internals
17929 // should be protected to avoid security holes, so yell loudly
17930 // to ensure we examine these cases.
17931 if (callerApp != null) {
17932 Log.wtf(TAG, "Sending non-protected broadcast " + action
17933 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17936 Log.wtf(TAG, "Sending non-protected broadcast " + action
17937 + " from system uid " + UserHandle.formatUid(callingUid)
17938 + " pkg " + callerPackage,
17943 final int broadcastIntentLocked(ProcessRecord callerApp,
17944 String callerPackage, Intent intent, String resolvedType,
17945 IIntentReceiver resultTo, int resultCode, String resultData,
17946 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17947 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17948 intent = new Intent(intent);
17950 // By default broadcasts do not go to stopped apps.
17951 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17953 // If we have not finished booting, don't allow this to launch new processes.
17954 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17955 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17958 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17959 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17960 + " ordered=" + ordered + " userid=" + userId);
17961 if ((resultTo != null) && !ordered) {
17962 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17965 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17966 ALLOW_NON_FULL, "broadcast", callerPackage);
17968 // Make sure that the user who is receiving this broadcast is running.
17969 // If not, we will just skip it. Make an exception for shutdown broadcasts
17970 // and upgrade steps.
17972 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17973 if ((callingUid != Process.SYSTEM_UID
17974 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17975 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17976 Slog.w(TAG, "Skipping broadcast of " + intent
17977 + ": user " + userId + " is stopped");
17978 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17982 BroadcastOptions brOptions = null;
17983 if (bOptions != null) {
17984 brOptions = new BroadcastOptions(bOptions);
17985 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17986 // See if the caller is allowed to do this. Note we are checking against
17987 // the actual real caller (not whoever provided the operation as say a
17988 // PendingIntent), because that who is actually supplied the arguments.
17989 if (checkComponentPermission(
17990 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17991 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17992 != PackageManager.PERMISSION_GRANTED) {
17993 String msg = "Permission Denial: " + intent.getAction()
17994 + " broadcast from " + callerPackage + " (pid=" + callingPid
17995 + ", uid=" + callingUid + ")"
17997 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17999 throw new SecurityException(msg);
18004 // Verify that protected broadcasts are only being sent by system code,
18005 // and that system code is only sending protected broadcasts.
18006 final String action = intent.getAction();
18007 final boolean isProtectedBroadcast;
18009 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18010 } catch (RemoteException e) {
18011 Slog.w(TAG, "Remote exception", e);
18012 return ActivityManager.BROADCAST_SUCCESS;
18015 final boolean isCallerSystem;
18016 switch (UserHandle.getAppId(callingUid)) {
18017 case Process.ROOT_UID:
18018 case Process.SYSTEM_UID:
18019 case Process.PHONE_UID:
18020 case Process.BLUETOOTH_UID:
18021 case Process.NFC_UID:
18022 isCallerSystem = true;
18025 isCallerSystem = (callerApp != null) && callerApp.persistent;
18029 // First line security check before anything else: stop non-system apps from
18030 // sending protected broadcasts.
18031 if (!isCallerSystem) {
18032 if (isProtectedBroadcast) {
18033 String msg = "Permission Denial: not allowed to send broadcast "
18034 + action + " from pid="
18035 + callingPid + ", uid=" + callingUid;
18037 throw new SecurityException(msg);
18039 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18040 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18041 // Special case for compatibility: we don't want apps to send this,
18042 // but historically it has not been protected and apps may be using it
18043 // to poke their own app widget. So, instead of making it protected,
18044 // just limit it to the caller.
18045 if (callerPackage == null) {
18046 String msg = "Permission Denial: not allowed to send broadcast "
18047 + action + " from unknown caller.";
18049 throw new SecurityException(msg);
18050 } else if (intent.getComponent() != null) {
18051 // They are good enough to send to an explicit component... verify
18052 // it is being sent to the calling app.
18053 if (!intent.getComponent().getPackageName().equals(
18055 String msg = "Permission Denial: not allowed to send broadcast "
18057 + intent.getComponent().getPackageName() + " from "
18060 throw new SecurityException(msg);
18063 // Limit broadcast to their own package.
18064 intent.setPackage(callerPackage);
18069 if (action != null) {
18071 case Intent.ACTION_UID_REMOVED:
18072 case Intent.ACTION_PACKAGE_REMOVED:
18073 case Intent.ACTION_PACKAGE_CHANGED:
18074 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18075 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18076 case Intent.ACTION_PACKAGES_SUSPENDED:
18077 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18078 // Handle special intents: if this broadcast is from the package
18079 // manager about a package being removed, we need to remove all of
18080 // its activities from the history stack.
18081 if (checkComponentPermission(
18082 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18083 callingPid, callingUid, -1, true)
18084 != PackageManager.PERMISSION_GRANTED) {
18085 String msg = "Permission Denial: " + intent.getAction()
18086 + " broadcast from " + callerPackage + " (pid=" + callingPid
18087 + ", uid=" + callingUid + ")"
18089 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18091 throw new SecurityException(msg);
18094 case Intent.ACTION_UID_REMOVED:
18095 final Bundle intentExtras = intent.getExtras();
18096 final int uid = intentExtras != null
18097 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18099 mBatteryStatsService.removeUid(uid);
18100 mAppOpsService.uidRemoved(uid);
18103 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18104 // If resources are unavailable just force stop all those packages
18105 // and flush the attribute cache as well.
18107 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18108 if (list != null && list.length > 0) {
18109 for (int i = 0; i < list.length; i++) {
18110 forceStopPackageLocked(list[i], -1, false, true, true,
18111 false, false, userId, "storage unmount");
18113 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18114 sendPackageBroadcastLocked(
18115 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18119 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18120 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18122 case Intent.ACTION_PACKAGE_REMOVED:
18123 case Intent.ACTION_PACKAGE_CHANGED:
18124 Uri data = intent.getData();
18126 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18127 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18128 final boolean replacing =
18129 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18130 final boolean killProcess =
18131 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18132 final boolean fullUninstall = removed && !replacing;
18135 forceStopPackageLocked(ssp, UserHandle.getAppId(
18136 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18137 false, true, true, false, fullUninstall, userId,
18138 removed ? "pkg removed" : "pkg changed");
18140 final int cmd = killProcess
18141 ? IApplicationThread.PACKAGE_REMOVED
18142 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18143 sendPackageBroadcastLocked(cmd,
18144 new String[] {ssp}, userId);
18145 if (fullUninstall) {
18146 mAppOpsService.packageRemoved(
18147 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18149 // Remove all permissions granted from/to this package
18150 removeUriPermissionsForPackageLocked(ssp, userId, true);
18152 removeTasksByPackageNameLocked(ssp, userId);
18154 // Hide the "unsupported display" dialog if necessary.
18155 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18156 mUnsupportedDisplaySizeDialog.getPackageName())) {
18157 mUnsupportedDisplaySizeDialog.dismiss();
18158 mUnsupportedDisplaySizeDialog = null;
18160 mCompatModePackages.handlePackageUninstalledLocked(ssp);
18161 mBatteryStatsService.notePackageUninstalled(ssp);
18165 killPackageProcessesLocked(ssp, UserHandle.getAppId(
18166 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18167 userId, ProcessList.INVALID_ADJ,
18168 false, true, true, false, "change " + ssp);
18170 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18171 intent.getStringArrayExtra(
18172 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18176 case Intent.ACTION_PACKAGES_SUSPENDED:
18177 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18178 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18179 intent.getAction());
18180 final String[] packageNames = intent.getStringArrayExtra(
18181 Intent.EXTRA_CHANGED_PACKAGE_LIST);
18182 final int userHandle = intent.getIntExtra(
18183 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18185 synchronized(ActivityManagerService.this) {
18186 mRecentTasks.onPackagesSuspendedChanged(
18187 packageNames, suspended, userHandle);
18192 case Intent.ACTION_PACKAGE_REPLACED:
18194 final Uri data = intent.getData();
18196 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18197 final ApplicationInfo aInfo =
18198 getPackageManagerInternalLocked().getApplicationInfo(
18201 if (aInfo == null) {
18202 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18203 + " ssp=" + ssp + " data=" + data);
18204 return ActivityManager.BROADCAST_SUCCESS;
18206 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18207 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18208 new String[] {ssp}, userId);
18212 case Intent.ACTION_PACKAGE_ADDED:
18214 // Special case for adding a package: by default turn on compatibility mode.
18215 Uri data = intent.getData();
18217 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18218 final boolean replacing =
18219 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18220 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18223 ApplicationInfo ai = AppGlobals.getPackageManager().
18224 getApplicationInfo(ssp, 0, 0);
18225 mBatteryStatsService.notePackageInstalled(ssp,
18226 ai != null ? ai.versionCode : 0);
18227 } catch (RemoteException e) {
18232 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18234 Uri data = intent.getData();
18236 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18237 // Hide the "unsupported display" dialog if necessary.
18238 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18239 mUnsupportedDisplaySizeDialog.getPackageName())) {
18240 mUnsupportedDisplaySizeDialog.dismiss();
18241 mUnsupportedDisplaySizeDialog = null;
18243 mCompatModePackages.handlePackageDataClearedLocked(ssp);
18247 case Intent.ACTION_TIMEZONE_CHANGED:
18248 // If this is the time zone changed action, queue up a message that will reset
18249 // the timezone of all currently running processes. This message will get
18250 // queued up before the broadcast happens.
18251 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18253 case Intent.ACTION_TIME_CHANGED:
18254 // If the user set the time, let all running processes know.
18255 final int is24Hour =
18256 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18258 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18259 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18260 synchronized (stats) {
18261 stats.noteCurrentTimeChangedLocked();
18264 case Intent.ACTION_CLEAR_DNS_CACHE:
18265 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18267 case Proxy.PROXY_CHANGE_ACTION:
18268 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18269 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18271 case android.hardware.Camera.ACTION_NEW_PICTURE:
18272 case android.hardware.Camera.ACTION_NEW_VIDEO:
18273 // These broadcasts are no longer allowed by the system, since they can
18274 // cause significant thrashing at a crictical point (using the camera).
18275 // Apps should use JobScehduler to monitor for media provider changes.
18276 Slog.w(TAG, action + " no longer allowed; dropping from "
18277 + UserHandle.formatUid(callingUid));
18278 if (resultTo != null) {
18279 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18281 queue.performReceiveLocked(callerApp, resultTo, intent,
18282 Activity.RESULT_CANCELED, null, null,
18283 false, false, userId);
18284 } catch (RemoteException e) {
18285 Slog.w(TAG, "Failure ["
18286 + queue.mQueueName + "] sending broadcast result of "
18291 // Lie; we don't want to crash the app.
18292 return ActivityManager.BROADCAST_SUCCESS;
18296 // Add to the sticky list if requested.
18298 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18299 callingPid, callingUid)
18300 != PackageManager.PERMISSION_GRANTED) {
18301 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18302 + callingPid + ", uid=" + callingUid
18303 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18305 throw new SecurityException(msg);
18307 if (requiredPermissions != null && requiredPermissions.length > 0) {
18308 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18309 + " and enforce permissions " + Arrays.toString(requiredPermissions));
18310 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18312 if (intent.getComponent() != null) {
18313 throw new SecurityException(
18314 "Sticky broadcasts can't target a specific component");
18316 // We use userId directly here, since the "all" target is maintained
18317 // as a separate set of sticky broadcasts.
18318 if (userId != UserHandle.USER_ALL) {
18319 // But first, if this is not a broadcast to all users, then
18320 // make sure it doesn't conflict with an existing broadcast to
18322 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18323 UserHandle.USER_ALL);
18324 if (stickies != null) {
18325 ArrayList<Intent> list = stickies.get(intent.getAction());
18326 if (list != null) {
18327 int N = list.size();
18329 for (i=0; i<N; i++) {
18330 if (intent.filterEquals(list.get(i))) {
18331 throw new IllegalArgumentException(
18332 "Sticky broadcast " + intent + " for user "
18333 + userId + " conflicts with existing global broadcast");
18339 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18340 if (stickies == null) {
18341 stickies = new ArrayMap<>();
18342 mStickyBroadcasts.put(userId, stickies);
18344 ArrayList<Intent> list = stickies.get(intent.getAction());
18345 if (list == null) {
18346 list = new ArrayList<>();
18347 stickies.put(intent.getAction(), list);
18349 final int stickiesCount = list.size();
18351 for (i = 0; i < stickiesCount; i++) {
18352 if (intent.filterEquals(list.get(i))) {
18353 // This sticky already exists, replace it.
18354 list.set(i, new Intent(intent));
18358 if (i >= stickiesCount) {
18359 list.add(new Intent(intent));
18364 if (userId == UserHandle.USER_ALL) {
18365 // Caller wants broadcast to go to all started users.
18366 users = mUserController.getStartedUserArrayLocked();
18368 // Caller wants broadcast to go to one specific user.
18369 users = new int[] {userId};
18372 // Figure out who all will receive this broadcast.
18373 List receivers = null;
18374 List<BroadcastFilter> registeredReceivers = null;
18375 // Need to resolve the intent to interested receivers...
18376 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18378 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18380 if (intent.getComponent() == null) {
18381 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18382 // Query one target user at a time, excluding shell-restricted users
18383 for (int i = 0; i < users.length; i++) {
18384 if (mUserController.hasUserRestriction(
18385 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18388 List<BroadcastFilter> registeredReceiversForUser =
18389 mReceiverResolver.queryIntent(intent,
18390 resolvedType, false, users[i]);
18391 if (registeredReceivers == null) {
18392 registeredReceivers = registeredReceiversForUser;
18393 } else if (registeredReceiversForUser != null) {
18394 registeredReceivers.addAll(registeredReceiversForUser);
18398 registeredReceivers = mReceiverResolver.queryIntent(intent,
18399 resolvedType, false, userId);
18403 final boolean replacePending =
18404 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18406 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18407 + " replacePending=" + replacePending);
18409 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18410 if (!ordered && NR > 0) {
18411 // If we are not serializing this broadcast, then send the
18412 // registered receivers separately so they don't wait for the
18413 // components to be launched.
18414 if (isCallerSystem) {
18415 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18416 isProtectedBroadcast, registeredReceivers);
18418 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18419 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18420 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18421 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18422 resultExtras, ordered, sticky, false, userId);
18423 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18424 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18426 queue.enqueueParallelBroadcastLocked(r);
18427 queue.scheduleBroadcastsLocked();
18429 registeredReceivers = null;
18433 // Merge into one list.
18435 if (receivers != null) {
18436 // A special case for PACKAGE_ADDED: do not allow the package
18437 // being added to see this broadcast. This prevents them from
18438 // using this as a back door to get run as soon as they are
18439 // installed. Maybe in the future we want to have a special install
18440 // broadcast or such for apps, but we'd like to deliberately make
18442 String skipPackages[] = null;
18443 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18444 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18445 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18446 Uri data = intent.getData();
18447 if (data != null) {
18448 String pkgName = data.getSchemeSpecificPart();
18449 if (pkgName != null) {
18450 skipPackages = new String[] { pkgName };
18453 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18454 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18456 if (skipPackages != null && (skipPackages.length > 0)) {
18457 for (String skipPackage : skipPackages) {
18458 if (skipPackage != null) {
18459 int NT = receivers.size();
18460 for (int it=0; it<NT; it++) {
18461 ResolveInfo curt = (ResolveInfo)receivers.get(it);
18462 if (curt.activityInfo.packageName.equals(skipPackage)) {
18463 receivers.remove(it);
18472 int NT = receivers != null ? receivers.size() : 0;
18474 ResolveInfo curt = null;
18475 BroadcastFilter curr = null;
18476 while (it < NT && ir < NR) {
18477 if (curt == null) {
18478 curt = (ResolveInfo)receivers.get(it);
18480 if (curr == null) {
18481 curr = registeredReceivers.get(ir);
18483 if (curr.getPriority() >= curt.priority) {
18484 // Insert this broadcast record into the final list.
18485 receivers.add(it, curr);
18491 // Skip to the next ResolveInfo in the final list.
18498 if (receivers == null) {
18499 receivers = new ArrayList();
18501 receivers.add(registeredReceivers.get(ir));
18505 if (isCallerSystem) {
18506 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18507 isProtectedBroadcast, receivers);
18510 if ((receivers != null && receivers.size() > 0)
18511 || resultTo != null) {
18512 BroadcastQueue queue = broadcastQueueForIntent(intent);
18513 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18514 callerPackage, callingPid, callingUid, resolvedType,
18515 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18516 resultData, resultExtras, ordered, sticky, false, userId);
18518 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18519 + ": prev had " + queue.mOrderedBroadcasts.size());
18520 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18521 "Enqueueing broadcast " + r.intent.getAction());
18523 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18525 queue.enqueueOrderedBroadcastLocked(r);
18526 queue.scheduleBroadcastsLocked();
18529 // There was nobody interested in the broadcast, but we still want to record
18530 // that it happened.
18531 if (intent.getComponent() == null && intent.getPackage() == null
18532 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18533 // This was an implicit broadcast... let's record it for posterity.
18534 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18538 return ActivityManager.BROADCAST_SUCCESS;
18541 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18542 int skipCount, long dispatchTime) {
18543 final long now = SystemClock.elapsedRealtime();
18544 if (mCurBroadcastStats == null ||
18545 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18546 mLastBroadcastStats = mCurBroadcastStats;
18547 if (mLastBroadcastStats != null) {
18548 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18549 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18551 mCurBroadcastStats = new BroadcastStats();
18553 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18556 final Intent verifyBroadcastLocked(Intent intent) {
18557 // Refuse possible leaked file descriptors
18558 if (intent != null && intent.hasFileDescriptors() == true) {
18559 throw new IllegalArgumentException("File descriptors passed in Intent");
18562 int flags = intent.getFlags();
18564 if (!mProcessesReady) {
18565 // if the caller really truly claims to know what they're doing, go
18566 // ahead and allow the broadcast without launching any receivers
18567 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18568 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18569 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18570 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18571 + " before boot completion");
18572 throw new IllegalStateException("Cannot broadcast before boot completed");
18576 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18577 throw new IllegalArgumentException(
18578 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18584 public final int broadcastIntent(IApplicationThread caller,
18585 Intent intent, String resolvedType, IIntentReceiver resultTo,
18586 int resultCode, String resultData, Bundle resultExtras,
18587 String[] requiredPermissions, int appOp, Bundle bOptions,
18588 boolean serialized, boolean sticky, int userId) {
18589 enforceNotIsolatedCaller("broadcastIntent");
18590 synchronized(this) {
18591 intent = verifyBroadcastLocked(intent);
18593 final ProcessRecord callerApp = getRecordForAppLocked(caller);
18594 final int callingPid = Binder.getCallingPid();
18595 final int callingUid = Binder.getCallingUid();
18596 final long origId = Binder.clearCallingIdentity();
18597 int res = broadcastIntentLocked(callerApp,
18598 callerApp != null ? callerApp.info.packageName : null,
18599 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18600 requiredPermissions, appOp, bOptions, serialized, sticky,
18601 callingPid, callingUid, userId);
18602 Binder.restoreCallingIdentity(origId);
18608 int broadcastIntentInPackage(String packageName, int uid,
18609 Intent intent, String resolvedType, IIntentReceiver resultTo,
18610 int resultCode, String resultData, Bundle resultExtras,
18611 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18613 synchronized(this) {
18614 intent = verifyBroadcastLocked(intent);
18616 final long origId = Binder.clearCallingIdentity();
18617 String[] requiredPermissions = requiredPermission == null ? null
18618 : new String[] {requiredPermission};
18619 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18620 resultTo, resultCode, resultData, resultExtras,
18621 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18622 sticky, -1, uid, userId);
18623 Binder.restoreCallingIdentity(origId);
18628 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18629 // Refuse possible leaked file descriptors
18630 if (intent != null && intent.hasFileDescriptors() == true) {
18631 throw new IllegalArgumentException("File descriptors passed in Intent");
18634 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18635 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18637 synchronized(this) {
18638 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18639 != PackageManager.PERMISSION_GRANTED) {
18640 String msg = "Permission Denial: unbroadcastIntent() from pid="
18641 + Binder.getCallingPid()
18642 + ", uid=" + Binder.getCallingUid()
18643 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18645 throw new SecurityException(msg);
18647 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18648 if (stickies != null) {
18649 ArrayList<Intent> list = stickies.get(intent.getAction());
18650 if (list != null) {
18651 int N = list.size();
18653 for (i=0; i<N; i++) {
18654 if (intent.filterEquals(list.get(i))) {
18659 if (list.size() <= 0) {
18660 stickies.remove(intent.getAction());
18663 if (stickies.size() <= 0) {
18664 mStickyBroadcasts.remove(userId);
18670 void backgroundServicesFinishedLocked(int userId) {
18671 for (BroadcastQueue queue : mBroadcastQueues) {
18672 queue.backgroundServicesFinishedLocked(userId);
18676 public void finishReceiver(IBinder who, int resultCode, String resultData,
18677 Bundle resultExtras, boolean resultAbort, int flags) {
18678 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18680 // Refuse possible leaked file descriptors
18681 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18682 throw new IllegalArgumentException("File descriptors passed in Bundle");
18685 final long origId = Binder.clearCallingIdentity();
18687 boolean doNext = false;
18690 synchronized(this) {
18691 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18692 ? mFgBroadcastQueue : mBgBroadcastQueue;
18693 r = queue.getMatchingOrderedReceiver(who);
18695 doNext = r.queue.finishReceiverLocked(r, resultCode,
18696 resultData, resultExtras, resultAbort, true);
18701 r.queue.processNextBroadcast(false);
18703 trimApplications();
18705 Binder.restoreCallingIdentity(origId);
18709 // =========================================================
18711 // =========================================================
18713 public boolean startInstrumentation(ComponentName className,
18714 String profileFile, int flags, Bundle arguments,
18715 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18716 int userId, String abiOverride) {
18717 enforceNotIsolatedCaller("startInstrumentation");
18718 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18719 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18720 // Refuse possible leaked file descriptors
18721 if (arguments != null && arguments.hasFileDescriptors()) {
18722 throw new IllegalArgumentException("File descriptors passed in Bundle");
18725 synchronized(this) {
18726 InstrumentationInfo ii = null;
18727 ApplicationInfo ai = null;
18729 ii = mContext.getPackageManager().getInstrumentationInfo(
18730 className, STOCK_PM_FLAGS);
18731 ai = AppGlobals.getPackageManager().getApplicationInfo(
18732 ii.targetPackage, STOCK_PM_FLAGS, userId);
18733 } catch (PackageManager.NameNotFoundException e) {
18734 } catch (RemoteException e) {
18737 reportStartInstrumentationFailureLocked(watcher, className,
18738 "Unable to find instrumentation info for: " + className);
18742 reportStartInstrumentationFailureLocked(watcher, className,
18743 "Unable to find instrumentation target package: " + ii.targetPackage);
18746 if (!ai.hasCode()) {
18747 reportStartInstrumentationFailureLocked(watcher, className,
18748 "Instrumentation target has no code: " + ii.targetPackage);
18752 int match = mContext.getPackageManager().checkSignatures(
18753 ii.targetPackage, ii.packageName);
18754 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18755 String msg = "Permission Denial: starting instrumentation "
18756 + className + " from pid="
18757 + Binder.getCallingPid()
18758 + ", uid=" + Binder.getCallingPid()
18759 + " not allowed because package " + ii.packageName
18760 + " does not have a signature matching the target "
18761 + ii.targetPackage;
18762 reportStartInstrumentationFailureLocked(watcher, className, msg);
18763 throw new SecurityException(msg);
18766 final long origId = Binder.clearCallingIdentity();
18767 // Instrumentation can kill and relaunch even persistent processes
18768 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18770 ProcessRecord app = addAppLocked(ai, false, abiOverride);
18771 app.instrumentationClass = className;
18772 app.instrumentationInfo = ai;
18773 app.instrumentationProfileFile = profileFile;
18774 app.instrumentationArguments = arguments;
18775 app.instrumentationWatcher = watcher;
18776 app.instrumentationUiAutomationConnection = uiAutomationConnection;
18777 app.instrumentationResultClass = className;
18778 Binder.restoreCallingIdentity(origId);
18785 * Report errors that occur while attempting to start Instrumentation. Always writes the
18786 * error to the logs, but if somebody is watching, send the report there too. This enables
18787 * the "am" command to report errors with more information.
18789 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
18790 * @param cn The component name of the instrumentation.
18791 * @param report The error report.
18793 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18794 ComponentName cn, String report) {
18795 Slog.w(TAG, report);
18796 if (watcher != null) {
18797 Bundle results = new Bundle();
18798 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18799 results.putString("Error", report);
18800 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18804 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18805 if (app.instrumentationWatcher != null) {
18806 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18807 app.instrumentationClass, resultCode, results);
18810 // Can't call out of the system process with a lock held, so post a message.
18811 if (app.instrumentationUiAutomationConnection != null) {
18812 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18813 app.instrumentationUiAutomationConnection).sendToTarget();
18816 app.instrumentationWatcher = null;
18817 app.instrumentationUiAutomationConnection = null;
18818 app.instrumentationClass = null;
18819 app.instrumentationInfo = null;
18820 app.instrumentationProfileFile = null;
18821 app.instrumentationArguments = null;
18823 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18827 public void finishInstrumentation(IApplicationThread target,
18828 int resultCode, Bundle results) {
18829 int userId = UserHandle.getCallingUserId();
18830 // Refuse possible leaked file descriptors
18831 if (results != null && results.hasFileDescriptors()) {
18832 throw new IllegalArgumentException("File descriptors passed in Intent");
18835 synchronized(this) {
18836 ProcessRecord app = getRecordForAppLocked(target);
18838 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18841 final long origId = Binder.clearCallingIdentity();
18842 finishInstrumentationLocked(app, resultCode, results);
18843 Binder.restoreCallingIdentity(origId);
18847 // =========================================================
18849 // =========================================================
18851 public ConfigurationInfo getDeviceConfigurationInfo() {
18852 ConfigurationInfo config = new ConfigurationInfo();
18853 synchronized (this) {
18854 config.reqTouchScreen = mConfiguration.touchscreen;
18855 config.reqKeyboardType = mConfiguration.keyboard;
18856 config.reqNavigation = mConfiguration.navigation;
18857 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18858 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18859 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18861 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18862 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18863 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18865 config.reqGlEsVersion = GL_ES_VERSION;
18870 ActivityStack getFocusedStack() {
18871 return mStackSupervisor.getFocusedStack();
18875 public int getFocusedStackId() throws RemoteException {
18876 ActivityStack focusedStack = getFocusedStack();
18877 if (focusedStack != null) {
18878 return focusedStack.getStackId();
18883 public Configuration getConfiguration() {
18885 synchronized(this) {
18886 ci = new Configuration(mConfiguration);
18887 ci.userSetLocale = false;
18893 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18894 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18895 synchronized (this) {
18896 mSuppressResizeConfigChanges = suppress;
18901 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18902 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18903 if (fromStackId == HOME_STACK_ID) {
18904 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18906 synchronized (this) {
18907 final long origId = Binder.clearCallingIdentity();
18909 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18911 Binder.restoreCallingIdentity(origId);
18917 public void updatePersistentConfiguration(Configuration values) {
18918 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18919 "updateConfiguration()");
18920 enforceWriteSettingsPermission("updateConfiguration()");
18921 if (values == null) {
18922 throw new NullPointerException("Configuration must not be null");
18925 int userId = UserHandle.getCallingUserId();
18927 synchronized(this) {
18928 updatePersistentConfigurationLocked(values, userId);
18932 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18933 final long origId = Binder.clearCallingIdentity();
18935 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18937 Binder.restoreCallingIdentity(origId);
18941 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18942 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18943 FONT_SCALE, 1.0f, userId);
18944 if (mConfiguration.fontScale != scaleFactor) {
18945 final Configuration configuration = mWindowManager.computeNewConfiguration();
18946 configuration.fontScale = scaleFactor;
18947 synchronized (this) {
18948 updatePersistentConfigurationLocked(configuration, userId);
18953 private void enforceWriteSettingsPermission(String func) {
18954 int uid = Binder.getCallingUid();
18955 if (uid == Process.ROOT_UID) {
18959 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18960 Settings.getPackageNameForUid(mContext, uid), false)) {
18964 String msg = "Permission Denial: " + func + " from pid="
18965 + Binder.getCallingPid()
18967 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18969 throw new SecurityException(msg);
18972 public void updateConfiguration(Configuration values) {
18973 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18974 "updateConfiguration()");
18976 synchronized(this) {
18977 if (values == null && mWindowManager != null) {
18978 // sentinel: fetch the current configuration from the window manager
18979 values = mWindowManager.computeNewConfiguration();
18982 if (mWindowManager != null) {
18983 mProcessList.applyDisplaySize(mWindowManager);
18986 final long origId = Binder.clearCallingIdentity();
18987 if (values != null) {
18988 Settings.System.clearConfiguration(values);
18990 updateConfigurationLocked(values, null, false);
18991 Binder.restoreCallingIdentity(origId);
18995 void updateUserConfigurationLocked() {
18996 Configuration configuration = new Configuration(mConfiguration);
18997 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18998 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18999 updateConfigurationLocked(configuration, null, false);
19002 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19003 boolean initLocale) {
19004 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19007 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19008 boolean initLocale, boolean deferResume) {
19009 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19010 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19011 UserHandle.USER_NULL, deferResume);
19014 // To cache the list of supported system locales
19015 private String[] mSupportedSystemLocales = null;
19018 * Do either or both things: (1) change the current configuration, and (2)
19019 * make sure the given activity is running with the (now) current
19020 * configuration. Returns true if the activity has been left running, or
19021 * false if <var>starting</var> is being destroyed to match the new
19024 * @param userId is only used when persistent parameter is set to true to persist configuration
19025 * for that particular user
19027 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19028 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19031 if (mWindowManager != null) {
19032 mWindowManager.deferSurfaceLayout();
19034 if (values != null) {
19035 Configuration newConfig = new Configuration(mConfiguration);
19036 changes = newConfig.updateFrom(values);
19037 if (changes != 0) {
19038 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19039 "Updating configuration to: " + values);
19041 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19043 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19044 final LocaleList locales = values.getLocales();
19045 int bestLocaleIndex = 0;
19046 if (locales.size() > 1) {
19047 if (mSupportedSystemLocales == null) {
19048 mSupportedSystemLocales =
19049 Resources.getSystem().getAssets().getLocales();
19051 bestLocaleIndex = Math.max(0,
19052 locales.getFirstMatchIndex(mSupportedSystemLocales));
19054 SystemProperties.set("persist.sys.locale",
19055 locales.get(bestLocaleIndex).toLanguageTag());
19056 LocaleList.setDefault(locales, bestLocaleIndex);
19057 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19058 locales.get(bestLocaleIndex)));
19061 mConfigurationSeq++;
19062 if (mConfigurationSeq <= 0) {
19063 mConfigurationSeq = 1;
19065 newConfig.seq = mConfigurationSeq;
19066 mConfiguration = newConfig;
19067 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19068 mUsageStatsService.reportConfigurationChange(newConfig,
19069 mUserController.getCurrentUserIdLocked());
19070 //mUsageStatsService.noteStartConfig(newConfig);
19072 final Configuration configCopy = new Configuration(mConfiguration);
19074 // TODO: If our config changes, should we auto dismiss any currently
19075 // showing dialogs?
19076 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19078 AttributeCache ac = AttributeCache.instance();
19080 ac.updateConfiguration(configCopy);
19083 // Make sure all resources in our process are updated
19084 // right now, so that anyone who is going to retrieve
19085 // resource values after we return will be sure to get
19086 // the new ones. This is especially important during
19087 // boot, where the first config change needs to guarantee
19088 // all resources have that config before following boot
19089 // code is executed.
19090 mSystemThread.applyConfigurationToResources(configCopy);
19092 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19093 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19094 msg.obj = new Configuration(configCopy);
19096 mHandler.sendMessage(msg);
19099 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19100 if (isDensityChange) {
19101 // Reset the unsupported display size dialog.
19102 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19104 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19105 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19108 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19109 ProcessRecord app = mLruProcesses.get(i);
19111 if (app.thread != null) {
19112 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19113 + app.processName + " new config " + mConfiguration);
19114 app.thread.scheduleConfigurationChanged(configCopy);
19116 } catch (Exception e) {
19119 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19120 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19121 | Intent.FLAG_RECEIVER_REPLACE_PENDING
19122 | Intent.FLAG_RECEIVER_FOREGROUND);
19123 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19124 null, AppOpsManager.OP_NONE, null, false, false,
19125 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19126 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19127 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19128 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19129 if (initLocale || !mProcessesReady) {
19130 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19132 broadcastIntentLocked(null, null, intent,
19133 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19134 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19137 // Update the configuration with WM first and check if any of the stacks need to be
19138 // resized due to the configuration change. If so, resize the stacks now and do any
19139 // relaunches if necessary. This way we don't need to relaunch again below in
19140 // ensureActivityConfigurationLocked().
19141 if (mWindowManager != null) {
19142 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19143 if (resizedStacks != null) {
19144 for (int stackId : resizedStacks) {
19145 final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19146 mStackSupervisor.resizeStackLocked(
19147 stackId, newBounds, null, null, false, false, deferResume);
19153 boolean kept = true;
19154 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19155 // mainStack is null during startup.
19156 if (mainStack != null) {
19157 if (changes != 0 && starting == null) {
19158 // If the configuration changed, and the caller is not already
19159 // in the process of starting an activity, then find the top
19160 // activity to check if its configuration needs to change.
19161 starting = mainStack.topRunningActivityLocked();
19164 if (starting != null) {
19165 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19166 // And we need to make sure at this point that all other activities
19167 // are made visible with the correct configuration.
19168 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19169 !PRESERVE_WINDOWS);
19172 if (mWindowManager != null) {
19173 mWindowManager.continueSurfaceLayout();
19179 * Decide based on the configuration whether we should shouw the ANR,
19180 * crash, etc dialogs. The idea is that if there is no affordence to
19181 * press the on-screen buttons, or the user experience would be more
19182 * greatly impacted than the crash itself, we shouldn't show the dialog.
19184 * A thought: SystemUI might also want to get told about this, the Power
19185 * dialog / global actions also might want different behaviors.
19187 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19188 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19189 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19190 && config.navigation == Configuration.NAVIGATION_NONAV);
19191 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19192 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19193 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19194 return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19198 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19199 synchronized (this) {
19200 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19201 if (srec != null) {
19202 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19208 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19209 Intent resultData) {
19211 synchronized (this) {
19212 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19214 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19220 public int getLaunchedFromUid(IBinder activityToken) {
19221 ActivityRecord srec;
19222 synchronized (this) {
19223 srec = ActivityRecord.forTokenLocked(activityToken);
19225 if (srec == null) {
19228 return srec.launchedFromUid;
19231 public String getLaunchedFromPackage(IBinder activityToken) {
19232 ActivityRecord srec;
19233 synchronized (this) {
19234 srec = ActivityRecord.forTokenLocked(activityToken);
19236 if (srec == null) {
19239 return srec.launchedFromPackage;
19242 // =========================================================
19243 // LIFETIME MANAGEMENT
19244 // =========================================================
19246 // Returns which broadcast queue the app is the current [or imminent] receiver
19247 // on, or 'null' if the app is not an active broadcast recipient.
19248 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19249 BroadcastRecord r = app.curReceiver;
19254 // It's not the current receiver, but it might be starting up to become one
19255 synchronized (this) {
19256 for (BroadcastQueue queue : mBroadcastQueues) {
19257 r = queue.mPendingBroadcast;
19258 if (r != null && r.curApp == app) {
19259 // found it; report which queue it's in
19268 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19269 int targetUid, ComponentName targetComponent, String targetProcess) {
19270 if (!mTrackingAssociations) {
19273 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19274 = mAssociations.get(targetUid);
19275 if (components == null) {
19276 components = new ArrayMap<>();
19277 mAssociations.put(targetUid, components);
19279 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19280 if (sourceUids == null) {
19281 sourceUids = new SparseArray<>();
19282 components.put(targetComponent, sourceUids);
19284 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19285 if (sourceProcesses == null) {
19286 sourceProcesses = new ArrayMap<>();
19287 sourceUids.put(sourceUid, sourceProcesses);
19289 Association ass = sourceProcesses.get(sourceProcess);
19291 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19293 sourceProcesses.put(sourceProcess, ass);
19297 if (ass.mNesting == 1) {
19298 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19299 ass.mLastState = sourceState;
19304 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19305 ComponentName targetComponent) {
19306 if (!mTrackingAssociations) {
19309 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19310 = mAssociations.get(targetUid);
19311 if (components == null) {
19314 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19315 if (sourceUids == null) {
19318 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19319 if (sourceProcesses == null) {
19322 Association ass = sourceProcesses.get(sourceProcess);
19323 if (ass == null || ass.mNesting <= 0) {
19327 if (ass.mNesting == 0) {
19328 long uptime = SystemClock.uptimeMillis();
19329 ass.mTime += uptime - ass.mStartTime;
19330 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19331 += uptime - ass.mLastStateUptime;
19332 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19336 private void noteUidProcessState(final int uid, final int state) {
19337 mBatteryStatsService.noteUidProcessState(uid, state);
19338 if (mTrackingAssociations) {
19339 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19340 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19341 = mAssociations.valueAt(i1);
19342 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19343 SparseArray<ArrayMap<String, Association>> sourceUids
19344 = targetComponents.valueAt(i2);
19345 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19346 if (sourceProcesses != null) {
19347 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19348 Association ass = sourceProcesses.valueAt(i4);
19349 if (ass.mNesting >= 1) {
19350 // currently associated
19351 long uptime = SystemClock.uptimeMillis();
19352 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19353 += uptime - ass.mLastStateUptime;
19354 ass.mLastState = state;
19355 ass.mLastStateUptime = uptime;
19364 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19365 boolean doingAll, long now) {
19366 if (mAdjSeq == app.adjSeq) {
19367 // This adjustment has already been computed.
19368 return app.curRawAdj;
19371 if (app.thread == null) {
19372 app.adjSeq = mAdjSeq;
19373 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19374 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19375 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19378 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19379 app.adjSource = null;
19380 app.adjTarget = null;
19382 app.cached = false;
19384 final int activitiesSize = app.activities.size();
19386 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19387 // The max adjustment doesn't allow this app to be anything
19388 // below foreground, so it is not worth doing work for it.
19389 app.adjType = "fixed";
19390 app.adjSeq = mAdjSeq;
19391 app.curRawAdj = app.maxAdj;
19392 app.foregroundActivities = false;
19393 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19394 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19395 // System processes can do UI, and when they do we want to have
19396 // them trim their memory after the user leaves the UI. To
19397 // facilitate this, here we need to determine whether or not it
19398 // is currently showing UI.
19399 app.systemNoUi = true;
19400 if (app == TOP_APP) {
19401 app.systemNoUi = false;
19402 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19403 app.adjType = "pers-top-activity";
19404 } else if (app.hasTopUi) {
19405 app.systemNoUi = false;
19406 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19407 app.adjType = "pers-top-ui";
19408 } else if (activitiesSize > 0) {
19409 for (int j = 0; j < activitiesSize; j++) {
19410 final ActivityRecord r = app.activities.get(j);
19412 app.systemNoUi = false;
19416 if (!app.systemNoUi) {
19417 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19419 return (app.curAdj=app.maxAdj);
19422 app.systemNoUi = false;
19424 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19426 // Determine the importance of the process, starting with most
19427 // important to least, and assign an appropriate OOM adjustment.
19431 boolean foregroundActivities = false;
19432 BroadcastQueue queue;
19433 if (app == TOP_APP) {
19434 // The last app on the list is the foreground app.
19435 adj = ProcessList.FOREGROUND_APP_ADJ;
19436 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19437 app.adjType = "top-activity";
19438 foregroundActivities = true;
19439 procState = PROCESS_STATE_CUR_TOP;
19440 } else if (app.instrumentationClass != null) {
19441 // Don't want to kill running instrumentation.
19442 adj = ProcessList.FOREGROUND_APP_ADJ;
19443 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19444 app.adjType = "instrumentation";
19445 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19446 } else if ((queue = isReceivingBroadcast(app)) != null) {
19447 // An app that is currently receiving a broadcast also
19448 // counts as being in the foreground for OOM killer purposes.
19449 // It's placed in a sched group based on the nature of the
19450 // broadcast as reflected by which queue it's active in.
19451 adj = ProcessList.FOREGROUND_APP_ADJ;
19452 schedGroup = (queue == mFgBroadcastQueue)
19453 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19454 app.adjType = "broadcast";
19455 procState = ActivityManager.PROCESS_STATE_RECEIVER;
19456 } else if (app.executingServices.size() > 0) {
19457 // An app that is currently executing a service callback also
19458 // counts as being in the foreground.
19459 adj = ProcessList.FOREGROUND_APP_ADJ;
19460 schedGroup = app.execServicesFg ?
19461 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19462 app.adjType = "exec-service";
19463 procState = ActivityManager.PROCESS_STATE_SERVICE;
19464 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19466 // As far as we know the process is empty. We may change our mind later.
19467 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19468 // At this point we don't actually know the adjustment. Use the cached adj
19469 // value that the caller wants us to.
19471 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19474 app.adjType = "cch-empty";
19477 // Examine all activities if not already foreground.
19478 if (!foregroundActivities && activitiesSize > 0) {
19479 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19480 for (int j = 0; j < activitiesSize; j++) {
19481 final ActivityRecord r = app.activities.get(j);
19482 if (r.app != app) {
19483 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19484 + " instead of expected " + app);
19485 if (r.app == null || (r.app.uid == app.uid)) {
19486 // Only fix things up when they look sane
19493 // App has a visible activity; only upgrade adjustment.
19494 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19495 adj = ProcessList.VISIBLE_APP_ADJ;
19496 app.adjType = "visible";
19498 if (procState > PROCESS_STATE_CUR_TOP) {
19499 procState = PROCESS_STATE_CUR_TOP;
19501 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19502 app.cached = false;
19504 foregroundActivities = true;
19505 if (r.task != null && minLayer > 0) {
19506 final int layer = r.task.mLayerRank;
19507 if (layer >= 0 && minLayer > layer) {
19512 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19513 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19514 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19515 app.adjType = "pausing";
19517 if (procState > PROCESS_STATE_CUR_TOP) {
19518 procState = PROCESS_STATE_CUR_TOP;
19520 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19521 app.cached = false;
19523 foregroundActivities = true;
19524 } else if (r.state == ActivityState.STOPPING) {
19525 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19526 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19527 app.adjType = "stopping";
19529 // For the process state, we will at this point consider the
19530 // process to be cached. It will be cached either as an activity
19531 // or empty depending on whether the activity is finishing. We do
19532 // this so that we can treat the process as cached for purposes of
19533 // memory trimming (determing current memory level, trim command to
19534 // send to process) since there can be an arbitrary number of stopping
19535 // processes and they should soon all go into the cached state.
19536 if (!r.finishing) {
19537 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19538 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19541 app.cached = false;
19543 foregroundActivities = true;
19545 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19546 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19547 app.adjType = "cch-act";
19551 if (adj == ProcessList.VISIBLE_APP_ADJ) {
19556 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19557 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19558 if (app.foregroundServices) {
19559 // The user is aware of this app, so make it visible.
19560 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19561 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19562 app.cached = false;
19563 app.adjType = "fg-service";
19564 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19565 } else if (app.forcingToForeground != null) {
19566 // The user is aware of this app, so make it visible.
19567 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19568 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19569 app.cached = false;
19570 app.adjType = "force-fg";
19571 app.adjSource = app.forcingToForeground;
19572 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19576 if (app == mHeavyWeightProcess) {
19577 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19578 // We don't want to kill the current heavy-weight process.
19579 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19580 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19581 app.cached = false;
19582 app.adjType = "heavy";
19584 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19585 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19589 if (app == mHomeProcess) {
19590 if (adj > ProcessList.HOME_APP_ADJ) {
19591 // This process is hosting what we currently consider to be the
19592 // home app, so we don't want to let it go into the background.
19593 adj = ProcessList.HOME_APP_ADJ;
19594 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19595 app.cached = false;
19596 app.adjType = "home";
19598 if (procState > ActivityManager.PROCESS_STATE_HOME) {
19599 procState = ActivityManager.PROCESS_STATE_HOME;
19603 if (app == mPreviousProcess && app.activities.size() > 0) {
19604 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19605 // This was the previous process that showed UI to the user.
19606 // We want to try to keep it around more aggressively, to give
19607 // a good experience around switching between two apps.
19608 adj = ProcessList.PREVIOUS_APP_ADJ;
19609 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19610 app.cached = false;
19611 app.adjType = "previous";
19613 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19614 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19618 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19619 + " reason=" + app.adjType);
19621 // By default, we use the computed adjustment. It may be changed if
19622 // there are applications dependent on our services or providers, but
19623 // this gives us a baseline and makes sure we don't get into an
19624 // infinite recursion.
19625 app.adjSeq = mAdjSeq;
19626 app.curRawAdj = adj;
19627 app.hasStartedServices = false;
19629 if (mBackupTarget != null && app == mBackupTarget.app) {
19630 // If possible we want to avoid killing apps while they're being backed up
19631 if (adj > ProcessList.BACKUP_APP_ADJ) {
19632 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19633 adj = ProcessList.BACKUP_APP_ADJ;
19634 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19635 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19637 app.adjType = "backup";
19638 app.cached = false;
19640 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19641 procState = ActivityManager.PROCESS_STATE_BACKUP;
19645 boolean mayBeTop = false;
19647 for (int is = app.services.size()-1;
19648 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19649 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19650 || procState > ActivityManager.PROCESS_STATE_TOP);
19652 ServiceRecord s = app.services.valueAt(is);
19653 if (s.startRequested) {
19654 app.hasStartedServices = true;
19655 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19656 procState = ActivityManager.PROCESS_STATE_SERVICE;
19658 if (app.hasShownUi && app != mHomeProcess) {
19659 // If this process has shown some UI, let it immediately
19660 // go to the LRU list because it may be pretty heavy with
19661 // UI stuff. We'll tag it with a label just to help
19662 // debug and understand what is going on.
19663 if (adj > ProcessList.SERVICE_ADJ) {
19664 app.adjType = "cch-started-ui-services";
19667 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19668 // This service has seen some activity within
19669 // recent memory, so we will keep its process ahead
19670 // of the background processes.
19671 if (adj > ProcessList.SERVICE_ADJ) {
19672 adj = ProcessList.SERVICE_ADJ;
19673 app.adjType = "started-services";
19674 app.cached = false;
19677 // If we have let the service slide into the background
19678 // state, still have some text describing what it is doing
19679 // even though the service no longer has an impact.
19680 if (adj > ProcessList.SERVICE_ADJ) {
19681 app.adjType = "cch-started-services";
19686 for (int conni = s.connections.size()-1;
19687 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19688 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19689 || procState > ActivityManager.PROCESS_STATE_TOP);
19691 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19693 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19694 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19695 || procState > ActivityManager.PROCESS_STATE_TOP);
19697 // XXX should compute this based on the max of
19698 // all connected clients.
19699 ConnectionRecord cr = clist.get(i);
19700 if (cr.binding.client == app) {
19701 // Binding to ourself is not interesting.
19705 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19706 ProcessRecord client = cr.binding.client;
19707 int clientAdj = computeOomAdjLocked(client, cachedAdj,
19708 TOP_APP, doingAll, now);
19709 int clientProcState = client.curProcState;
19710 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19711 // If the other app is cached for any reason, for purposes here
19712 // we are going to consider it empty. The specific cached state
19713 // doesn't propagate except under certain conditions.
19714 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19716 String adjType = null;
19717 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19718 // Not doing bind OOM management, so treat
19719 // this guy more like a started service.
19720 if (app.hasShownUi && app != mHomeProcess) {
19721 // If this process has shown some UI, let it immediately
19722 // go to the LRU list because it may be pretty heavy with
19723 // UI stuff. We'll tag it with a label just to help
19724 // debug and understand what is going on.
19725 if (adj > clientAdj) {
19726 adjType = "cch-bound-ui-services";
19728 app.cached = false;
19730 clientProcState = procState;
19732 if (now >= (s.lastActivity
19733 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19734 // This service has not seen activity within
19735 // recent memory, so allow it to drop to the
19736 // LRU list if there is no other reason to keep
19737 // it around. We'll also tag it with a label just
19738 // to help debug and undertand what is going on.
19739 if (adj > clientAdj) {
19740 adjType = "cch-bound-services";
19746 if (adj > clientAdj) {
19747 // If this process has recently shown UI, and
19748 // the process that is binding to it is less
19749 // important than being visible, then we don't
19750 // care about the binding as much as we care
19751 // about letting this process get into the LRU
19752 // list to be killed and restarted if needed for
19754 if (app.hasShownUi && app != mHomeProcess
19755 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19756 adjType = "cch-bound-ui-services";
19758 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19759 |Context.BIND_IMPORTANT)) != 0) {
19760 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19761 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19762 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19763 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19764 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19765 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19766 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19769 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19770 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19773 if (!client.cached) {
19774 app.cached = false;
19776 adjType = "service";
19779 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19780 // This will treat important bound services identically to
19781 // the top app, which may behave differently than generic
19782 // foreground work.
19783 if (client.curSchedGroup > schedGroup) {
19784 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19785 schedGroup = client.curSchedGroup;
19787 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19790 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19791 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19792 // Special handling of clients who are in the top state.
19793 // We *may* want to consider this process to be in the
19794 // top state as well, but only if there is not another
19795 // reason for it to be running. Being on the top is a
19796 // special state, meaning you are specifically running
19797 // for the current top app. If the process is already
19798 // running in the background for some other reason, it
19799 // is more important to continue considering it to be
19800 // in the background state.
19802 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19804 // Special handling for above-top states (persistent
19805 // processes). These should not bring the current process
19806 // into the top state, since they are not on top. Instead
19807 // give them the best state after that.
19808 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19810 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19811 } else if (mWakefulness
19812 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19813 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19816 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19819 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19824 if (clientProcState <
19825 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19827 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19830 if (procState > clientProcState) {
19831 procState = clientProcState;
19833 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19834 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19835 app.pendingUiClean = true;
19837 if (adjType != null) {
19838 app.adjType = adjType;
19839 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19840 .REASON_SERVICE_IN_USE;
19841 app.adjSource = cr.binding.client;
19842 app.adjSourceProcState = clientProcState;
19843 app.adjTarget = s.name;
19846 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19847 app.treatLikeActivity = true;
19849 final ActivityRecord a = cr.activity;
19850 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19851 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19852 (a.visible || a.state == ActivityState.RESUMED ||
19853 a.state == ActivityState.PAUSING)) {
19854 adj = ProcessList.FOREGROUND_APP_ADJ;
19855 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19856 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19857 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19859 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19862 app.cached = false;
19863 app.adjType = "service";
19864 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19865 .REASON_SERVICE_IN_USE;
19867 app.adjSourceProcState = procState;
19868 app.adjTarget = s.name;
19875 for (int provi = app.pubProviders.size()-1;
19876 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19877 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19878 || procState > ActivityManager.PROCESS_STATE_TOP);
19880 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19881 for (int i = cpr.connections.size()-1;
19882 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19883 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19884 || procState > ActivityManager.PROCESS_STATE_TOP);
19886 ContentProviderConnection conn = cpr.connections.get(i);
19887 ProcessRecord client = conn.client;
19888 if (client == app) {
19889 // Being our own client is not interesting.
19892 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19893 int clientProcState = client.curProcState;
19894 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19895 // If the other app is cached for any reason, for purposes here
19896 // we are going to consider it empty.
19897 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19899 if (adj > clientAdj) {
19900 if (app.hasShownUi && app != mHomeProcess
19901 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19902 app.adjType = "cch-ui-provider";
19904 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19905 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19906 app.adjType = "provider";
19908 app.cached &= client.cached;
19909 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19910 .REASON_PROVIDER_IN_USE;
19911 app.adjSource = client;
19912 app.adjSourceProcState = clientProcState;
19913 app.adjTarget = cpr.name;
19915 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19916 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19917 // Special handling of clients who are in the top state.
19918 // We *may* want to consider this process to be in the
19919 // top state as well, but only if there is not another
19920 // reason for it to be running. Being on the top is a
19921 // special state, meaning you are specifically running
19922 // for the current top app. If the process is already
19923 // running in the background for some other reason, it
19924 // is more important to continue considering it to be
19925 // in the background state.
19927 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19929 // Special handling for above-top states (persistent
19930 // processes). These should not bring the current process
19931 // into the top state, since they are not on top. Instead
19932 // give them the best state after that.
19934 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19937 if (procState > clientProcState) {
19938 procState = clientProcState;
19940 if (client.curSchedGroup > schedGroup) {
19941 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19944 // If the provider has external (non-framework) process
19945 // dependencies, ensure that its adjustment is at least
19946 // FOREGROUND_APP_ADJ.
19947 if (cpr.hasExternalProcessHandles()) {
19948 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19949 adj = ProcessList.FOREGROUND_APP_ADJ;
19950 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19951 app.cached = false;
19952 app.adjType = "provider";
19953 app.adjTarget = cpr.name;
19955 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19956 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19961 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19962 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19963 adj = ProcessList.PREVIOUS_APP_ADJ;
19964 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19965 app.cached = false;
19966 app.adjType = "provider";
19968 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19969 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19973 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19974 // A client of one of our services or providers is in the top state. We
19975 // *may* want to be in the top state, but not if we are already running in
19976 // the background for some other reason. For the decision here, we are going
19977 // to pick out a few specific states that we want to remain in when a client
19978 // is top (states that tend to be longer-term) and otherwise allow it to go
19979 // to the top state.
19980 switch (procState) {
19981 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19982 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19983 case ActivityManager.PROCESS_STATE_SERVICE:
19984 // These all are longer-term states, so pull them up to the top
19985 // of the background states, but not all the way to the top state.
19986 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19989 // Otherwise, top is a better choice, so take it.
19990 procState = ActivityManager.PROCESS_STATE_TOP;
19995 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19996 if (app.hasClientActivities) {
19997 // This is a cached process, but with client activities. Mark it so.
19998 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19999 app.adjType = "cch-client-act";
20000 } else if (app.treatLikeActivity) {
20001 // This is a cached process, but somebody wants us to treat it like it has
20002 // an activity, okay!
20003 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20004 app.adjType = "cch-as-act";
20008 if (adj == ProcessList.SERVICE_ADJ) {
20010 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20011 mNewNumServiceProcs++;
20012 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20013 if (!app.serviceb) {
20014 // This service isn't far enough down on the LRU list to
20015 // normally be a B service, but if we are low on RAM and it
20016 // is large we want to force it down since we would prefer to
20017 // keep launcher over it.
20018 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20019 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20020 app.serviceHighRam = true;
20021 app.serviceb = true;
20022 //Slog.i(TAG, "ADJ " + app + " high ram!");
20024 mNewNumAServiceProcs++;
20025 //Slog.i(TAG, "ADJ " + app + " not high ram!");
20028 app.serviceHighRam = false;
20031 if (app.serviceb) {
20032 adj = ProcessList.SERVICE_B_ADJ;
20036 app.curRawAdj = adj;
20038 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20039 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20040 if (adj > app.maxAdj) {
20042 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20043 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20047 // Do final modification to adj. Everything we do between here and applying
20048 // the final setAdj must be done in this function, because we will also use
20049 // it when computing the final cached adj later. Note that we don't need to
20050 // worry about this for max adj above, since max adj will always be used to
20051 // keep it out of the cached vaues.
20052 app.curAdj = app.modifyRawOomAdj(adj);
20053 app.curSchedGroup = schedGroup;
20054 app.curProcState = procState;
20055 app.foregroundActivities = foregroundActivities;
20057 return app.curRawAdj;
20061 * Record new PSS sample for a process.
20063 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20065 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20067 proc.lastPssTime = now;
20068 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20069 if (DEBUG_PSS) Slog.d(TAG_PSS,
20070 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20071 + " state=" + ProcessList.makeProcStateString(procState));
20072 if (proc.initialIdlePss == 0) {
20073 proc.initialIdlePss = pss;
20075 proc.lastPss = pss;
20076 proc.lastSwapPss = swapPss;
20077 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20078 proc.lastCachedPss = pss;
20079 proc.lastCachedSwapPss = swapPss;
20082 final SparseArray<Pair<Long, String>> watchUids
20083 = mMemWatchProcesses.getMap().get(proc.processName);
20085 if (watchUids != null) {
20086 Pair<Long, String> val = watchUids.get(proc.uid);
20088 val = watchUids.get(0);
20094 if (check != null) {
20095 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20096 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20097 if (!isDebuggable) {
20098 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20099 isDebuggable = true;
20102 if (isDebuggable) {
20103 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20104 final ProcessRecord myProc = proc;
20105 final File heapdumpFile = DumpHeapProvider.getJavaFile();
20106 mMemWatchDumpProcName = proc.processName;
20107 mMemWatchDumpFile = heapdumpFile.toString();
20108 mMemWatchDumpPid = proc.pid;
20109 mMemWatchDumpUid = proc.uid;
20110 BackgroundThread.getHandler().post(new Runnable() {
20112 public void run() {
20113 revokeUriPermission(ActivityThread.currentActivityThread()
20114 .getApplicationThread(),
20115 DumpHeapActivity.JAVA_URI,
20116 Intent.FLAG_GRANT_READ_URI_PERMISSION
20117 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20118 UserHandle.myUserId());
20119 ParcelFileDescriptor fd = null;
20121 heapdumpFile.delete();
20122 fd = ParcelFileDescriptor.open(heapdumpFile,
20123 ParcelFileDescriptor.MODE_CREATE |
20124 ParcelFileDescriptor.MODE_TRUNCATE |
20125 ParcelFileDescriptor.MODE_WRITE_ONLY |
20126 ParcelFileDescriptor.MODE_APPEND);
20127 IApplicationThread thread = myProc.thread;
20128 if (thread != null) {
20130 if (DEBUG_PSS) Slog.d(TAG_PSS,
20131 "Requesting dump heap from "
20132 + myProc + " to " + heapdumpFile);
20133 thread.dumpHeap(true, heapdumpFile.toString(), fd);
20134 } catch (RemoteException e) {
20137 } catch (FileNotFoundException e) {
20138 e.printStackTrace();
20143 } catch (IOException e) {
20150 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20151 + ", but debugging not enabled");
20158 * Schedule PSS collection of a process.
20160 void requestPssLocked(ProcessRecord proc, int procState) {
20161 if (mPendingPssProcesses.contains(proc)) {
20164 if (mPendingPssProcesses.size() == 0) {
20165 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20167 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20168 proc.pssProcState = procState;
20169 mPendingPssProcesses.add(proc);
20173 * Schedule PSS collection of all processes.
20175 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20177 if (now < (mLastFullPssTime +
20178 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20182 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
20183 mLastFullPssTime = now;
20184 mFullPssPending = true;
20185 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20186 mPendingPssProcesses.clear();
20187 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20188 ProcessRecord app = mLruProcesses.get(i);
20189 if (app.thread == null
20190 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20193 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20194 app.pssProcState = app.setProcState;
20195 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20196 mTestPssMode, isSleepingLocked(), now);
20197 mPendingPssProcesses.add(app);
20200 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20203 public void setTestPssMode(boolean enabled) {
20204 synchronized (this) {
20205 mTestPssMode = enabled;
20207 // Whenever we enable the mode, we want to take a snapshot all of current
20208 // process mem use.
20209 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20215 * Ask a given process to GC right now.
20217 final void performAppGcLocked(ProcessRecord app) {
20219 app.lastRequestedGc = SystemClock.uptimeMillis();
20220 if (app.thread != null) {
20221 if (app.reportLowMemory) {
20222 app.reportLowMemory = false;
20223 app.thread.scheduleLowMemory();
20225 app.thread.processInBackground();
20228 } catch (Exception e) {
20234 * Returns true if things are idle enough to perform GCs.
20236 private final boolean canGcNowLocked() {
20237 boolean processingBroadcasts = false;
20238 for (BroadcastQueue q : mBroadcastQueues) {
20239 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20240 processingBroadcasts = true;
20243 return !processingBroadcasts
20244 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20248 * Perform GCs on all processes that are waiting for it, but only
20249 * if things are idle.
20251 final void performAppGcsLocked() {
20252 final int N = mProcessesToGc.size();
20256 if (canGcNowLocked()) {
20257 while (mProcessesToGc.size() > 0) {
20258 ProcessRecord proc = mProcessesToGc.remove(0);
20259 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20260 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20261 <= SystemClock.uptimeMillis()) {
20262 // To avoid spamming the system, we will GC processes one
20263 // at a time, waiting a few seconds between each.
20264 performAppGcLocked(proc);
20265 scheduleAppGcsLocked();
20268 // It hasn't been long enough since we last GCed this
20269 // process... put it in the list to wait for its time.
20270 addProcessToGcListLocked(proc);
20276 scheduleAppGcsLocked();
20281 * If all looks good, perform GCs on all processes waiting for them.
20283 final void performAppGcsIfAppropriateLocked() {
20284 if (canGcNowLocked()) {
20285 performAppGcsLocked();
20288 // Still not idle, wait some more.
20289 scheduleAppGcsLocked();
20293 * Schedule the execution of all pending app GCs.
20295 final void scheduleAppGcsLocked() {
20296 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20298 if (mProcessesToGc.size() > 0) {
20299 // Schedule a GC for the time to the next process.
20300 ProcessRecord proc = mProcessesToGc.get(0);
20301 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20303 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20304 long now = SystemClock.uptimeMillis();
20305 if (when < (now+GC_TIMEOUT)) {
20306 when = now + GC_TIMEOUT;
20308 mHandler.sendMessageAtTime(msg, when);
20313 * Add a process to the array of processes waiting to be GCed. Keeps the
20314 * list in sorted order by the last GC time. The process can't already be
20317 final void addProcessToGcListLocked(ProcessRecord proc) {
20318 boolean added = false;
20319 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20320 if (mProcessesToGc.get(i).lastRequestedGc <
20321 proc.lastRequestedGc) {
20323 mProcessesToGc.add(i+1, proc);
20328 mProcessesToGc.add(0, proc);
20333 * Set up to ask a process to GC itself. This will either do it
20334 * immediately, or put it on the list of processes to gc the next
20335 * time things are idle.
20337 final void scheduleAppGcLocked(ProcessRecord app) {
20338 long now = SystemClock.uptimeMillis();
20339 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20342 if (!mProcessesToGc.contains(app)) {
20343 addProcessToGcListLocked(app);
20344 scheduleAppGcsLocked();
20348 final void checkExcessivePowerUsageLocked(boolean doKills) {
20349 updateCpuStatsNow();
20351 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20352 boolean doWakeKills = doKills;
20353 boolean doCpuKills = doKills;
20354 if (mLastPowerCheckRealtime == 0) {
20355 doWakeKills = false;
20357 if (mLastPowerCheckUptime == 0) {
20358 doCpuKills = false;
20360 if (stats.isScreenOn()) {
20361 doWakeKills = false;
20363 final long curRealtime = SystemClock.elapsedRealtime();
20364 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20365 final long curUptime = SystemClock.uptimeMillis();
20366 final long uptimeSince = curUptime - mLastPowerCheckUptime;
20367 mLastPowerCheckRealtime = curRealtime;
20368 mLastPowerCheckUptime = curUptime;
20369 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20370 doWakeKills = false;
20372 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20373 doCpuKills = false;
20375 int i = mLruProcesses.size();
20378 ProcessRecord app = mLruProcesses.get(i);
20379 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20381 synchronized (stats) {
20382 wtime = stats.getProcessWakeTime(app.info.uid,
20383 app.pid, curRealtime);
20385 long wtimeUsed = wtime - app.lastWakeTime;
20386 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20388 StringBuilder sb = new StringBuilder(128);
20389 sb.append("Wake for ");
20390 app.toShortString(sb);
20391 sb.append(": over ");
20392 TimeUtils.formatDuration(realtimeSince, sb);
20393 sb.append(" used ");
20394 TimeUtils.formatDuration(wtimeUsed, sb);
20396 sb.append((wtimeUsed*100)/realtimeSince);
20398 Slog.i(TAG_POWER, sb.toString());
20400 sb.append("CPU for ");
20401 app.toShortString(sb);
20402 sb.append(": over ");
20403 TimeUtils.formatDuration(uptimeSince, sb);
20404 sb.append(" used ");
20405 TimeUtils.formatDuration(cputimeUsed, sb);
20407 sb.append((cputimeUsed*100)/uptimeSince);
20409 Slog.i(TAG_POWER, sb.toString());
20411 // If a process has held a wake lock for more
20412 // than 50% of the time during this period,
20413 // that sounds bad. Kill!
20414 if (doWakeKills && realtimeSince > 0
20415 && ((wtimeUsed*100)/realtimeSince) >= 50) {
20416 synchronized (stats) {
20417 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20418 realtimeSince, wtimeUsed);
20420 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20421 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20422 } else if (doCpuKills && uptimeSince > 0
20423 && ((cputimeUsed*100)/uptimeSince) >= 25) {
20424 synchronized (stats) {
20425 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20426 uptimeSince, cputimeUsed);
20428 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20429 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20431 app.lastWakeTime = wtime;
20432 app.lastCpuTime = app.curCpuTime;
20438 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20440 boolean success = true;
20442 if (app.curRawAdj != app.setRawAdj) {
20443 app.setRawAdj = app.curRawAdj;
20448 if (app.curAdj != app.setAdj) {
20449 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20450 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20451 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20453 app.setAdj = app.curAdj;
20454 app.verifiedAdj = ProcessList.INVALID_ADJ;
20457 if (app.setSchedGroup != app.curSchedGroup) {
20458 int oldSchedGroup = app.setSchedGroup;
20459 app.setSchedGroup = app.curSchedGroup;
20460 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20461 "Setting sched group of " + app.processName
20462 + " to " + app.curSchedGroup);
20463 if (app.waitingToKill != null && app.curReceiver == null
20464 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20465 app.kill(app.waitingToKill, true);
20469 switch (app.curSchedGroup) {
20470 case ProcessList.SCHED_GROUP_BACKGROUND:
20471 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20473 case ProcessList.SCHED_GROUP_TOP_APP:
20474 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20475 processGroup = Process.THREAD_GROUP_TOP_APP;
20478 processGroup = Process.THREAD_GROUP_DEFAULT;
20481 long oldId = Binder.clearCallingIdentity();
20483 Process.setProcessGroup(app.pid, processGroup);
20484 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20485 // do nothing if we already switched to RT
20486 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20487 // Switch VR thread for app to SCHED_FIFO
20488 if (mInVrMode && app.vrThreadTid != 0) {
20490 Process.setThreadScheduler(app.vrThreadTid,
20491 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20492 } catch (IllegalArgumentException e) {
20493 // thread died, ignore
20496 if (mUseFifoUiScheduling) {
20497 // Switch UI pipeline for app to SCHED_FIFO
20498 app.savedPriority = Process.getThreadPriority(app.pid);
20500 Process.setThreadScheduler(app.pid,
20501 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20502 } catch (IllegalArgumentException e) {
20503 // thread died, ignore
20505 if (app.renderThreadTid != 0) {
20507 Process.setThreadScheduler(app.renderThreadTid,
20508 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20509 } catch (IllegalArgumentException e) {
20510 // thread died, ignore
20512 if (DEBUG_OOM_ADJ) {
20513 Slog.d("UI_FIFO", "Set RenderThread (TID " +
20514 app.renderThreadTid + ") to FIFO");
20517 if (DEBUG_OOM_ADJ) {
20518 Slog.d("UI_FIFO", "Not setting RenderThread TID");
20522 // Boost priority for top app UI and render threads
20523 Process.setThreadPriority(app.pid, -10);
20524 if (app.renderThreadTid != 0) {
20526 Process.setThreadPriority(app.renderThreadTid, -10);
20527 } catch (IllegalArgumentException e) {
20528 // thread died, ignore
20533 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20534 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20535 // Reset VR thread to SCHED_OTHER
20536 // Safe to do even if we're not in VR mode
20537 if (app.vrThreadTid != 0) {
20538 Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20540 if (mUseFifoUiScheduling) {
20541 // Reset UI pipeline to SCHED_OTHER
20542 Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20543 Process.setThreadPriority(app.pid, app.savedPriority);
20544 if (app.renderThreadTid != 0) {
20545 Process.setThreadScheduler(app.renderThreadTid,
20546 Process.SCHED_OTHER, 0);
20547 Process.setThreadPriority(app.renderThreadTid, -4);
20550 // Reset priority for top app UI and render threads
20551 Process.setThreadPriority(app.pid, 0);
20552 if (app.renderThreadTid != 0) {
20553 Process.setThreadPriority(app.renderThreadTid, 0);
20557 } catch (Exception e) {
20558 Slog.w(TAG, "Failed setting process group of " + app.pid
20559 + " to " + app.curSchedGroup);
20560 e.printStackTrace();
20562 Binder.restoreCallingIdentity(oldId);
20566 if (app.repForegroundActivities != app.foregroundActivities) {
20567 app.repForegroundActivities = app.foregroundActivities;
20568 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20570 if (app.repProcState != app.curProcState) {
20571 app.repProcState = app.curProcState;
20572 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20573 if (app.thread != null) {
20576 //RuntimeException h = new RuntimeException("here");
20577 Slog.i(TAG, "Sending new process state " + app.repProcState
20578 + " to " + app /*, h*/);
20580 app.thread.setProcessState(app.repProcState);
20581 } catch (RemoteException e) {
20585 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20586 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20587 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20588 // Experimental code to more aggressively collect pss while
20589 // running test... the problem is that this tends to collect
20590 // the data right when a process is transitioning between process
20591 // states, which well tend to give noisy data.
20592 long start = SystemClock.uptimeMillis();
20593 long pss = Debug.getPss(app.pid, mTmpLong, null);
20594 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20595 mPendingPssProcesses.remove(app);
20596 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20597 + " to " + app.curProcState + ": "
20598 + (SystemClock.uptimeMillis()-start) + "ms");
20600 app.lastStateTime = now;
20601 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20602 mTestPssMode, isSleepingLocked(), now);
20603 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20604 + ProcessList.makeProcStateString(app.setProcState) + " to "
20605 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20606 + (app.nextPssTime-now) + ": " + app);
20608 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20609 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20611 requestPssLocked(app, app.setProcState);
20612 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20613 mTestPssMode, isSleepingLocked(), now);
20614 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20615 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20617 if (app.setProcState != app.curProcState) {
20618 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20619 "Proc state change of " + app.processName
20620 + " to " + app.curProcState);
20621 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20622 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20623 if (setImportant && !curImportant) {
20624 // This app is no longer something we consider important enough to allow to
20625 // use arbitrary amounts of battery power. Note
20626 // its current wake lock time to later know to kill it if
20627 // it is not behaving well.
20628 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20629 synchronized (stats) {
20630 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20631 app.pid, nowElapsed);
20633 app.lastCpuTime = app.curCpuTime;
20636 // Inform UsageStats of important process state change
20637 // Must be called before updating setProcState
20638 maybeUpdateUsageStatsLocked(app, nowElapsed);
20640 app.setProcState = app.curProcState;
20641 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20642 app.notCachedSinceIdle = false;
20645 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20647 app.procStateChanged = true;
20649 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20650 > USAGE_STATS_INTERACTION_INTERVAL) {
20651 // For apps that sit around for a long time in the interactive state, we need
20652 // to report this at least once a day so they don't go idle.
20653 maybeUpdateUsageStatsLocked(app, nowElapsed);
20656 if (changes != 0) {
20657 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20658 "Changes in " + app + ": " + changes);
20659 int i = mPendingProcessChanges.size()-1;
20660 ProcessChangeItem item = null;
20662 item = mPendingProcessChanges.get(i);
20663 if (item.pid == app.pid) {
20664 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20665 "Re-using existing item: " + item);
20671 // No existing item in pending changes; need a new one.
20672 final int NA = mAvailProcessChanges.size();
20674 item = mAvailProcessChanges.remove(NA-1);
20675 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20676 "Retrieving available item: " + item);
20678 item = new ProcessChangeItem();
20679 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20680 "Allocating new item: " + item);
20683 item.pid = app.pid;
20684 item.uid = app.info.uid;
20685 if (mPendingProcessChanges.size() == 0) {
20686 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20687 "*** Enqueueing dispatch processes changed!");
20688 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20690 mPendingProcessChanges.add(item);
20692 item.changes |= changes;
20693 item.processState = app.repProcState;
20694 item.foregroundActivities = app.repForegroundActivities;
20695 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20696 "Item " + Integer.toHexString(System.identityHashCode(item))
20697 + " " + app.toShortString() + ": changes=" + item.changes
20698 + " procState=" + item.processState
20699 + " foreground=" + item.foregroundActivities
20700 + " type=" + app.adjType + " source=" + app.adjSource
20701 + " target=" + app.adjTarget);
20707 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20708 final UidRecord.ChangeItem pendingChange;
20709 if (uidRec == null || uidRec.pendingChange == null) {
20710 if (mPendingUidChanges.size() == 0) {
20711 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20712 "*** Enqueueing dispatch uid changed!");
20713 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20715 final int NA = mAvailUidChanges.size();
20717 pendingChange = mAvailUidChanges.remove(NA-1);
20718 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20719 "Retrieving available item: " + pendingChange);
20721 pendingChange = new UidRecord.ChangeItem();
20722 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20723 "Allocating new item: " + pendingChange);
20725 if (uidRec != null) {
20726 uidRec.pendingChange = pendingChange;
20727 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20728 // If this uid is going away, and we haven't yet reported it is gone,
20730 change = UidRecord.CHANGE_GONE_IDLE;
20732 } else if (uid < 0) {
20733 throw new IllegalArgumentException("No UidRecord or uid");
20735 pendingChange.uidRecord = uidRec;
20736 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20737 mPendingUidChanges.add(pendingChange);
20739 pendingChange = uidRec.pendingChange;
20740 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20741 change = UidRecord.CHANGE_GONE_IDLE;
20744 pendingChange.change = change;
20745 pendingChange.processState = uidRec != null
20746 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20749 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20750 String authority) {
20751 if (app == null) return;
20752 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20753 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20754 if (userState == null) return;
20755 final long now = SystemClock.elapsedRealtime();
20756 Long lastReported = userState.mProviderLastReportedFg.get(authority);
20757 if (lastReported == null || lastReported < now - 60 * 1000L) {
20758 if (mSystemReady) {
20759 // Cannot touch the user stats if not system ready
20760 mUsageStatsService.reportContentProviderUsage(
20761 authority, providerPkgName, app.userId);
20763 userState.mProviderLastReportedFg.put(authority, now);
20768 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20769 if (DEBUG_USAGE_STATS) {
20770 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20771 + "] state changes: old = " + app.setProcState + ", new = "
20772 + app.curProcState);
20774 if (mUsageStatsService == null) {
20777 boolean isInteraction;
20778 // To avoid some abuse patterns, we are going to be careful about what we consider
20779 // to be an app interaction. Being the top activity doesn't count while the display
20780 // is sleeping, nor do short foreground services.
20781 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20782 isInteraction = true;
20783 app.fgInteractionTime = 0;
20784 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20785 if (app.fgInteractionTime == 0) {
20786 app.fgInteractionTime = nowElapsed;
20787 isInteraction = false;
20789 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20792 // If the app was being forced to the foreground, by say a Toast, then
20793 // no need to treat it as an interaction
20794 isInteraction = app.forcingToForeground == null
20795 && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20796 app.fgInteractionTime = 0;
20798 if (isInteraction && (!app.reportedInteraction
20799 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20800 app.interactionEventTime = nowElapsed;
20801 String[] packages = app.getPackageList();
20802 if (packages != null) {
20803 for (int i = 0; i < packages.length; i++) {
20804 mUsageStatsService.reportEvent(packages[i], app.userId,
20805 UsageEvents.Event.SYSTEM_INTERACTION);
20809 app.reportedInteraction = isInteraction;
20810 if (!isInteraction) {
20811 app.interactionEventTime = 0;
20815 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20816 if (proc.thread != null) {
20817 if (proc.baseProcessTracker != null) {
20818 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20823 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20824 ProcessRecord TOP_APP, boolean doingAll, long now) {
20825 if (app.thread == null) {
20829 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20831 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20834 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20836 if (isForeground != proc.foregroundServices) {
20837 proc.foregroundServices = isForeground;
20838 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20840 if (isForeground) {
20841 if (curProcs == null) {
20842 curProcs = new ArrayList<ProcessRecord>();
20843 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20845 if (!curProcs.contains(proc)) {
20846 curProcs.add(proc);
20847 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20848 proc.info.packageName, proc.info.uid);
20851 if (curProcs != null) {
20852 if (curProcs.remove(proc)) {
20853 mBatteryStatsService.noteEvent(
20854 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20855 proc.info.packageName, proc.info.uid);
20856 if (curProcs.size() <= 0) {
20857 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20863 updateOomAdjLocked();
20868 private final ActivityRecord resumedAppLocked() {
20869 ActivityRecord act = mStackSupervisor.resumedAppLocked();
20873 pkg = act.packageName;
20874 uid = act.info.applicationInfo.uid;
20879 // Has the UID or resumed package name changed?
20880 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20881 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20882 if (mCurResumedPackage != null) {
20883 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20884 mCurResumedPackage, mCurResumedUid);
20886 mCurResumedPackage = pkg;
20887 mCurResumedUid = uid;
20888 if (mCurResumedPackage != null) {
20889 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20890 mCurResumedPackage, mCurResumedUid);
20896 final boolean updateOomAdjLocked(ProcessRecord app) {
20897 final ActivityRecord TOP_ACT = resumedAppLocked();
20898 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20899 final boolean wasCached = app.cached;
20903 // This is the desired cached adjusment we want to tell it to use.
20904 // If our app is currently cached, we know it, and that is it. Otherwise,
20905 // we don't know it yet, and it needs to now be cached we will then
20906 // need to do a complete oom adj.
20907 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20908 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20909 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20910 SystemClock.uptimeMillis());
20911 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20912 // Changed to/from cached state, so apps after it in the LRU
20913 // list may also be changed.
20914 updateOomAdjLocked();
20919 final void updateOomAdjLocked() {
20920 final ActivityRecord TOP_ACT = resumedAppLocked();
20921 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20922 final long now = SystemClock.uptimeMillis();
20923 final long nowElapsed = SystemClock.elapsedRealtime();
20924 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20925 final int N = mLruProcesses.size();
20928 RuntimeException e = new RuntimeException();
20929 e.fillInStackTrace();
20930 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20933 // Reset state in all uid records.
20934 for (int i=mActiveUids.size()-1; i>=0; i--) {
20935 final UidRecord uidRec = mActiveUids.valueAt(i);
20936 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20937 "Starting update of " + uidRec);
20941 mStackSupervisor.rankTaskLayersIfNeeded();
20944 mNewNumServiceProcs = 0;
20945 mNewNumAServiceProcs = 0;
20947 final int emptyProcessLimit;
20948 final int cachedProcessLimit;
20949 if (mProcessLimit <= 0) {
20950 emptyProcessLimit = cachedProcessLimit = 0;
20951 } else if (mProcessLimit == 1) {
20952 emptyProcessLimit = 1;
20953 cachedProcessLimit = 0;
20955 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20956 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20959 // Let's determine how many processes we have running vs.
20960 // how many slots we have for background processes; we may want
20961 // to put multiple processes in a slot of there are enough of
20963 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20964 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20965 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20966 if (numEmptyProcs > cachedProcessLimit) {
20967 // If there are more empty processes than our limit on cached
20968 // processes, then use the cached process limit for the factor.
20969 // This ensures that the really old empty processes get pushed
20970 // down to the bottom, so if we are running low on memory we will
20971 // have a better chance at keeping around more cached processes
20972 // instead of a gazillion empty processes.
20973 numEmptyProcs = cachedProcessLimit;
20975 int emptyFactor = numEmptyProcs/numSlots;
20976 if (emptyFactor < 1) emptyFactor = 1;
20977 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20978 if (cachedFactor < 1) cachedFactor = 1;
20979 int stepCached = 0;
20983 int numTrimming = 0;
20985 mNumNonCachedProcs = 0;
20986 mNumCachedHiddenProcs = 0;
20988 // First update the OOM adjustment for each of the
20989 // application processes based on their current state.
20990 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20991 int nextCachedAdj = curCachedAdj+1;
20992 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20993 int nextEmptyAdj = curEmptyAdj+2;
20994 for (int i=N-1; i>=0; i--) {
20995 ProcessRecord app = mLruProcesses.get(i);
20999 if (!app.killedByAm && app.thread != null) {
21000 app.procStateChanged = false;
21001 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21003 // If we haven't yet assigned the final cached adj
21004 // to the process, do that now.
21005 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21006 switch (app.curProcState) {
21007 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21008 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21009 // This process is a cached process holding activities...
21010 // assign it the next cached value for that type, and then
21011 // step that cached level.
21012 app.curRawAdj = curCachedAdj;
21013 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21014 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21015 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21017 if (curCachedAdj != nextCachedAdj) {
21019 if (stepCached >= cachedFactor) {
21021 curCachedAdj = nextCachedAdj;
21022 nextCachedAdj += 2;
21023 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21024 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21030 // For everything else, assign next empty cached process
21031 // level and bump that up. Note that this means that
21032 // long-running services that have dropped down to the
21033 // cached level will be treated as empty (since their process
21034 // state is still as a service), which is what we want.
21035 app.curRawAdj = curEmptyAdj;
21036 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21037 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21038 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21040 if (curEmptyAdj != nextEmptyAdj) {
21042 if (stepEmpty >= emptyFactor) {
21044 curEmptyAdj = nextEmptyAdj;
21046 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21047 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21055 applyOomAdjLocked(app, true, now, nowElapsed);
21057 // Count the number of process types.
21058 switch (app.curProcState) {
21059 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21060 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21061 mNumCachedHiddenProcs++;
21063 if (numCached > cachedProcessLimit) {
21064 app.kill("cached #" + numCached, true);
21067 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21068 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21069 && app.lastActivityTime < oldTime) {
21070 app.kill("empty for "
21071 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21072 / 1000) + "s", true);
21075 if (numEmpty > emptyProcessLimit) {
21076 app.kill("empty #" + numEmpty, true);
21081 mNumNonCachedProcs++;
21085 if (app.isolated && app.services.size() <= 0) {
21086 // If this is an isolated process, and there are no
21087 // services running in it, then the process is no longer
21088 // needed. We agressively kill these because we can by
21089 // definition not re-use the same process again, and it is
21090 // good to avoid having whatever code was running in them
21091 // left sitting around after no longer needed.
21092 app.kill("isolated not needed", true);
21094 // Keeping this process, update its uid.
21095 final UidRecord uidRec = app.uidRecord;
21096 if (uidRec != null && uidRec.curProcState > app.curProcState) {
21097 uidRec.curProcState = app.curProcState;
21101 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21102 && !app.killedByAm) {
21108 mNumServiceProcs = mNewNumServiceProcs;
21110 // Now determine the memory trimming level of background processes.
21111 // Unfortunately we need to start at the back of the list to do this
21112 // properly. We only do this if the number of background apps we
21113 // are managing to keep around is less than half the maximum we desire;
21114 // if we are keeping a good number around, we'll let them use whatever
21115 // memory they want.
21116 final int numCachedAndEmpty = numCached + numEmpty;
21118 if (numCached <= ProcessList.TRIM_CACHED_APPS
21119 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21120 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21121 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21122 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21123 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21125 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21128 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21130 // We always allow the memory level to go up (better). We only allow it to go
21131 // down if we are in a state where that is allowed, *and* the total number of processes
21132 // has gone down since last time.
21133 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21134 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21135 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21136 if (memFactor > mLastMemoryLevel) {
21137 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21138 memFactor = mLastMemoryLevel;
21139 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21142 if (memFactor != mLastMemoryLevel) {
21143 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21145 mLastMemoryLevel = memFactor;
21146 mLastNumProcesses = mLruProcesses.size();
21147 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21148 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21149 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21150 if (mLowRamStartTime == 0) {
21151 mLowRamStartTime = now;
21155 switch (memFactor) {
21156 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21157 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21159 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21160 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21163 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21166 int factor = numTrimming/3;
21168 if (mHomeProcess != null) minFactor++;
21169 if (mPreviousProcess != null) minFactor++;
21170 if (factor < minFactor) factor = minFactor;
21171 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21172 for (int i=N-1; i>=0; i--) {
21173 ProcessRecord app = mLruProcesses.get(i);
21177 if (allChanged || app.procStateChanged) {
21178 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21179 app.procStateChanged = false;
21181 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21182 && !app.killedByAm) {
21183 if (app.trimMemoryLevel < curLevel && app.thread != null) {
21185 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21186 "Trimming memory of " + app.processName + " to " + curLevel);
21187 app.thread.scheduleTrimMemory(curLevel);
21188 } catch (RemoteException e) {
21191 // For now we won't do this; our memory trimming seems
21192 // to be good enough at this point that destroying
21193 // activities causes more harm than good.
21194 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21195 && app != mHomeProcess && app != mPreviousProcess) {
21196 // Need to do this on its own message because the stack may not
21197 // be in a consistent state at this point.
21198 // For these apps we will also finish their activities
21199 // to help them free memory.
21200 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21204 app.trimMemoryLevel = curLevel;
21206 if (step >= factor) {
21208 switch (curLevel) {
21209 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21210 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21212 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21213 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21217 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21218 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21219 && app.thread != null) {
21221 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21222 "Trimming memory of heavy-weight " + app.processName
21223 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21224 app.thread.scheduleTrimMemory(
21225 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21226 } catch (RemoteException e) {
21229 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21231 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21232 || app.systemNoUi) && app.pendingUiClean) {
21233 // If this application is now in the background and it
21234 // had done UI, then give it the special trim level to
21235 // have it free UI resources.
21236 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21237 if (app.trimMemoryLevel < level && app.thread != null) {
21239 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21240 "Trimming memory of bg-ui " + app.processName
21242 app.thread.scheduleTrimMemory(level);
21243 } catch (RemoteException e) {
21246 app.pendingUiClean = false;
21248 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21250 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21251 "Trimming memory of fg " + app.processName
21252 + " to " + fgTrimLevel);
21253 app.thread.scheduleTrimMemory(fgTrimLevel);
21254 } catch (RemoteException e) {
21257 app.trimMemoryLevel = fgTrimLevel;
21261 if (mLowRamStartTime != 0) {
21262 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21263 mLowRamStartTime = 0;
21265 for (int i=N-1; i>=0; i--) {
21266 ProcessRecord app = mLruProcesses.get(i);
21267 if (allChanged || app.procStateChanged) {
21268 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21269 app.procStateChanged = false;
21271 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21272 || app.systemNoUi) && app.pendingUiClean) {
21273 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21274 && app.thread != null) {
21276 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21277 "Trimming memory of ui hidden " + app.processName
21278 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21279 app.thread.scheduleTrimMemory(
21280 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21281 } catch (RemoteException e) {
21284 app.pendingUiClean = false;
21286 app.trimMemoryLevel = 0;
21290 if (mAlwaysFinishActivities) {
21291 // Need to do this on its own message because the stack may not
21292 // be in a consistent state at this point.
21293 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21297 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21300 // Update from any uid changes.
21301 for (int i=mActiveUids.size()-1; i>=0; i--) {
21302 final UidRecord uidRec = mActiveUids.valueAt(i);
21303 int uidChange = UidRecord.CHANGE_PROCSTATE;
21304 if (uidRec.setProcState != uidRec.curProcState) {
21305 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21306 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21307 + " to " + uidRec.curProcState);
21308 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21309 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21310 uidRec.lastBackgroundTime = nowElapsed;
21311 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21312 // Note: the background settle time is in elapsed realtime, while
21313 // the handler time base is uptime. All this means is that we may
21314 // stop background uids later than we had intended, but that only
21315 // happens because the device was sleeping so we are okay anyway.
21316 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21321 uidChange = UidRecord.CHANGE_ACTIVE;
21322 uidRec.idle = false;
21324 uidRec.lastBackgroundTime = 0;
21326 uidRec.setProcState = uidRec.curProcState;
21327 enqueueUidChangeLocked(uidRec, -1, uidChange);
21328 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21332 if (mProcessStats.shouldWriteNowLocked(now)) {
21333 mHandler.post(new Runnable() {
21334 @Override public void run() {
21335 synchronized (ActivityManagerService.this) {
21336 mProcessStats.writeStateAsyncLocked();
21342 if (DEBUG_OOM_ADJ) {
21343 final long duration = SystemClock.uptimeMillis() - now;
21345 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21346 new RuntimeException("here").fillInStackTrace());
21348 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21353 final void idleUids() {
21354 synchronized (this) {
21355 final long nowElapsed = SystemClock.elapsedRealtime();
21356 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21358 for (int i=mActiveUids.size()-1; i>=0; i--) {
21359 final UidRecord uidRec = mActiveUids.valueAt(i);
21360 final long bgTime = uidRec.lastBackgroundTime;
21361 if (bgTime > 0 && !uidRec.idle) {
21362 if (bgTime <= maxBgTime) {
21363 uidRec.idle = true;
21364 doStopUidLocked(uidRec.uid, uidRec);
21366 if (nextTime == 0 || nextTime > bgTime) {
21372 if (nextTime > 0) {
21373 mHandler.removeMessages(IDLE_UIDS_MSG);
21374 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21375 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21380 final void runInBackgroundDisabled(int uid) {
21381 synchronized (this) {
21382 UidRecord uidRec = mActiveUids.get(uid);
21383 if (uidRec != null) {
21384 // This uid is actually running... should it be considered background now?
21386 doStopUidLocked(uidRec.uid, uidRec);
21389 // This uid isn't actually running... still send a report about it being "stopped".
21390 doStopUidLocked(uid, null);
21395 final void doStopUidLocked(int uid, final UidRecord uidRec) {
21396 mServices.stopInBackgroundLocked(uid);
21397 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21400 final void trimApplications() {
21401 synchronized (this) {
21404 // First remove any unused application processes whose package
21405 // has been removed.
21406 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21407 final ProcessRecord app = mRemovedProcesses.get(i);
21408 if (app.activities.size() == 0
21409 && app.curReceiver == null && app.services.size() == 0) {
21411 TAG, "Exiting empty application process "
21412 + app.toShortString() + " ("
21413 + (app.thread != null ? app.thread.asBinder() : null)
21415 if (app.pid > 0 && app.pid != MY_PID) {
21416 app.kill("empty", false);
21419 app.thread.scheduleExit();
21420 } catch (Exception e) {
21421 // Ignore exceptions.
21424 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21425 mRemovedProcesses.remove(i);
21427 if (app.persistent) {
21428 addAppLocked(app.info, false, null /* ABI override */);
21433 // Now update the oom adj for all processes.
21434 updateOomAdjLocked();
21438 /** This method sends the specified signal to each of the persistent apps */
21439 public void signalPersistentProcesses(int sig) throws RemoteException {
21440 if (sig != Process.SIGNAL_USR1) {
21441 throw new SecurityException("Only SIGNAL_USR1 is allowed");
21444 synchronized (this) {
21445 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21446 != PackageManager.PERMISSION_GRANTED) {
21447 throw new SecurityException("Requires permission "
21448 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21451 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21452 ProcessRecord r = mLruProcesses.get(i);
21453 if (r.thread != null && r.persistent) {
21454 Process.sendSignal(r.pid, sig);
21460 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21461 if (proc == null || proc == mProfileProc) {
21462 proc = mProfileProc;
21463 profileType = mProfileType;
21464 clearProfilerLocked();
21466 if (proc == null) {
21470 proc.thread.profilerControl(false, null, profileType);
21471 } catch (RemoteException e) {
21472 throw new IllegalStateException("Process disappeared");
21476 private void clearProfilerLocked() {
21477 if (mProfileFd != null) {
21479 mProfileFd.close();
21480 } catch (IOException e) {
21483 mProfileApp = null;
21484 mProfileProc = null;
21485 mProfileFile = null;
21487 mAutoStopProfiler = false;
21488 mSamplingInterval = 0;
21491 public boolean profileControl(String process, int userId, boolean start,
21492 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21495 synchronized (this) {
21496 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21497 // its own permission.
21498 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21499 != PackageManager.PERMISSION_GRANTED) {
21500 throw new SecurityException("Requires permission "
21501 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21504 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21505 throw new IllegalArgumentException("null profile info or fd");
21508 ProcessRecord proc = null;
21509 if (process != null) {
21510 proc = findProcessLocked(process, userId, "profileControl");
21513 if (start && (proc == null || proc.thread == null)) {
21514 throw new IllegalArgumentException("Unknown process: " + process);
21518 stopProfilerLocked(null, 0);
21519 setProfileApp(proc.info, proc.processName, profilerInfo);
21520 mProfileProc = proc;
21521 mProfileType = profileType;
21522 ParcelFileDescriptor fd = profilerInfo.profileFd;
21525 } catch (IOException e) {
21528 profilerInfo.profileFd = fd;
21529 proc.thread.profilerControl(start, profilerInfo, profileType);
21533 stopProfilerLocked(proc, profileType);
21534 if (profilerInfo != null && profilerInfo.profileFd != null) {
21536 profilerInfo.profileFd.close();
21537 } catch (IOException e) {
21544 } catch (RemoteException e) {
21545 throw new IllegalStateException("Process disappeared");
21547 if (profilerInfo != null && profilerInfo.profileFd != null) {
21549 profilerInfo.profileFd.close();
21550 } catch (IOException e) {
21556 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21557 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21558 userId, true, ALLOW_FULL_ONLY, callName, null);
21559 ProcessRecord proc = null;
21561 int pid = Integer.parseInt(process);
21562 synchronized (mPidsSelfLocked) {
21563 proc = mPidsSelfLocked.get(pid);
21565 } catch (NumberFormatException e) {
21568 if (proc == null) {
21569 ArrayMap<String, SparseArray<ProcessRecord>> all
21570 = mProcessNames.getMap();
21571 SparseArray<ProcessRecord> procs = all.get(process);
21572 if (procs != null && procs.size() > 0) {
21573 proc = procs.valueAt(0);
21574 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21575 for (int i=1; i<procs.size(); i++) {
21576 ProcessRecord thisProc = procs.valueAt(i);
21577 if (thisProc.userId == userId) {
21589 public boolean dumpHeap(String process, int userId, boolean managed,
21590 String path, ParcelFileDescriptor fd) throws RemoteException {
21593 synchronized (this) {
21594 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21595 // its own permission (same as profileControl).
21596 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21597 != PackageManager.PERMISSION_GRANTED) {
21598 throw new SecurityException("Requires permission "
21599 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21603 throw new IllegalArgumentException("null fd");
21606 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21607 if (proc == null || proc.thread == null) {
21608 throw new IllegalArgumentException("Unknown process: " + process);
21611 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21612 if (!isDebuggable) {
21613 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21614 throw new SecurityException("Process not debuggable: " + proc);
21618 proc.thread.dumpHeap(managed, path, fd);
21622 } catch (RemoteException e) {
21623 throw new IllegalStateException("Process disappeared");
21628 } catch (IOException e) {
21635 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21636 String reportPackage) {
21637 if (processName != null) {
21638 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21639 "setDumpHeapDebugLimit()");
21641 synchronized (mPidsSelfLocked) {
21642 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21643 if (proc == null) {
21644 throw new SecurityException("No process found for calling pid "
21645 + Binder.getCallingPid());
21647 if (!Build.IS_DEBUGGABLE
21648 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21649 throw new SecurityException("Not running a debuggable build");
21651 processName = proc.processName;
21653 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21654 throw new SecurityException("Package " + reportPackage + " is not running in "
21659 synchronized (this) {
21660 if (maxMemSize > 0) {
21661 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21664 mMemWatchProcesses.remove(processName, uid);
21666 mMemWatchProcesses.getMap().remove(processName);
21673 public void dumpHeapFinished(String path) {
21674 synchronized (this) {
21675 if (Binder.getCallingPid() != mMemWatchDumpPid) {
21676 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21677 + " does not match last pid " + mMemWatchDumpPid);
21680 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21681 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21682 + " does not match last path " + mMemWatchDumpFile);
21685 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21686 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21690 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21691 public void monitor() {
21692 synchronized (this) { }
21695 void onCoreSettingsChange(Bundle settings) {
21696 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21697 ProcessRecord processRecord = mLruProcesses.get(i);
21699 if (processRecord.thread != null) {
21700 processRecord.thread.setCoreSettings(settings);
21702 } catch (RemoteException re) {
21708 // Multi-user methods
21711 * Start user, if its not already running, but don't bring it to foreground.
21714 public boolean startUserInBackground(final int userId) {
21715 return mUserController.startUser(userId, /* foreground */ false);
21719 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21720 return mUserController.unlockUser(userId, token, secret, listener);
21724 public boolean switchUser(final int targetUserId) {
21725 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21726 UserInfo currentUserInfo;
21727 UserInfo targetUserInfo;
21728 synchronized (this) {
21729 int currentUserId = mUserController.getCurrentUserIdLocked();
21730 currentUserInfo = mUserController.getUserInfo(currentUserId);
21731 targetUserInfo = mUserController.getUserInfo(targetUserId);
21732 if (targetUserInfo == null) {
21733 Slog.w(TAG, "No user info for user #" + targetUserId);
21736 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21737 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21738 + " when device is in demo mode");
21741 if (!targetUserInfo.supportsSwitchTo()) {
21742 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21745 if (targetUserInfo.isManagedProfile()) {
21746 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21749 mUserController.setTargetUserIdLocked(targetUserId);
21751 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21752 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21753 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21757 void scheduleStartProfilesLocked() {
21758 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21759 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21760 DateUtils.SECOND_IN_MILLIS);
21765 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21766 return mUserController.stopUser(userId, force, callback);
21770 public UserInfo getCurrentUser() {
21771 return mUserController.getCurrentUser();
21775 public boolean isUserRunning(int userId, int flags) {
21776 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21777 && checkCallingPermission(INTERACT_ACROSS_USERS)
21778 != PackageManager.PERMISSION_GRANTED) {
21779 String msg = "Permission Denial: isUserRunning() from pid="
21780 + Binder.getCallingPid()
21781 + ", uid=" + Binder.getCallingUid()
21782 + " requires " + INTERACT_ACROSS_USERS;
21784 throw new SecurityException(msg);
21786 synchronized (this) {
21787 return mUserController.isUserRunningLocked(userId, flags);
21792 public int[] getRunningUserIds() {
21793 if (checkCallingPermission(INTERACT_ACROSS_USERS)
21794 != PackageManager.PERMISSION_GRANTED) {
21795 String msg = "Permission Denial: isUserRunning() from pid="
21796 + Binder.getCallingPid()
21797 + ", uid=" + Binder.getCallingUid()
21798 + " requires " + INTERACT_ACROSS_USERS;
21800 throw new SecurityException(msg);
21802 synchronized (this) {
21803 return mUserController.getStartedUserArrayLocked();
21808 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21809 mUserController.registerUserSwitchObserver(observer, name);
21813 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21814 mUserController.unregisterUserSwitchObserver(observer);
21817 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21818 if (info == null) return null;
21819 ApplicationInfo newInfo = new ApplicationInfo(info);
21820 newInfo.initForUser(userId);
21824 public boolean isUserStopped(int userId) {
21825 synchronized (this) {
21826 return mUserController.getStartedUserStateLocked(userId) == null;
21830 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21832 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21836 ActivityInfo info = new ActivityInfo(aInfo);
21837 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21841 private boolean processSanityChecksLocked(ProcessRecord process) {
21842 if (process == null || process.thread == null) {
21846 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21847 if (!isDebuggable) {
21848 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21856 public boolean startBinderTracking() throws RemoteException {
21857 synchronized (this) {
21858 mBinderTransactionTrackingEnabled = true;
21859 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21860 // permission (same as profileControl).
21861 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21862 != PackageManager.PERMISSION_GRANTED) {
21863 throw new SecurityException("Requires permission "
21864 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21867 for (int i = 0; i < mLruProcesses.size(); i++) {
21868 ProcessRecord process = mLruProcesses.get(i);
21869 if (!processSanityChecksLocked(process)) {
21873 process.thread.startBinderTracking();
21874 } catch (RemoteException e) {
21875 Log.v(TAG, "Process disappared");
21882 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21884 synchronized (this) {
21885 mBinderTransactionTrackingEnabled = false;
21886 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21887 // permission (same as profileControl).
21888 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21889 != PackageManager.PERMISSION_GRANTED) {
21890 throw new SecurityException("Requires permission "
21891 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21895 throw new IllegalArgumentException("null fd");
21898 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21899 pw.println("Binder transaction traces for all processes.\n");
21900 for (ProcessRecord process : mLruProcesses) {
21901 if (!processSanityChecksLocked(process)) {
21905 pw.println("Traces for process: " + process.processName);
21908 TransferPipe tp = new TransferPipe();
21910 process.thread.stopBinderTrackingAndDump(
21911 tp.getWriteFd().getFileDescriptor());
21912 tp.go(fd.getFileDescriptor());
21916 } catch (IOException e) {
21917 pw.println("Failure while dumping IPC traces from " + process +
21918 ". Exception: " + e);
21920 } catch (RemoteException e) {
21921 pw.println("Got a RemoteException while dumping IPC traces from " +
21922 process + ". Exception: " + e);
21933 } catch (IOException e) {
21939 private final class LocalService extends ActivityManagerInternal {
21941 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
21942 int targetUserId) {
21943 synchronized (ActivityManagerService.this) {
21944 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
21945 targetPkg, intent, null, targetUserId);
21950 public String checkContentProviderAccess(String authority, int userId) {
21951 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21955 public void onWakefulnessChanged(int wakefulness) {
21956 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21960 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21961 String processName, String abiOverride, int uid, Runnable crashHandler) {
21962 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21963 processName, abiOverride, uid, crashHandler);
21967 public SleepToken acquireSleepToken(String tag) {
21968 Preconditions.checkNotNull(tag);
21970 synchronized (ActivityManagerService.this) {
21971 SleepTokenImpl token = new SleepTokenImpl(tag);
21972 mSleepTokens.add(token);
21973 updateSleepIfNeededLocked();
21979 public ComponentName getHomeActivityForUser(int userId) {
21980 synchronized (ActivityManagerService.this) {
21981 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21982 return homeActivity == null ? null : homeActivity.realActivity;
21987 public void onUserRemoved(int userId) {
21988 synchronized (ActivityManagerService.this) {
21989 ActivityManagerService.this.onUserStoppedLocked(userId);
21994 public void onLocalVoiceInteractionStarted(IBinder activity,
21995 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21996 synchronized (ActivityManagerService.this) {
21997 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21998 voiceSession, voiceInteractor);
22003 public void notifyStartingWindowDrawn() {
22004 synchronized (ActivityManagerService.this) {
22005 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22010 public void notifyAppTransitionStarting(int reason) {
22011 synchronized (ActivityManagerService.this) {
22012 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22017 public void notifyAppTransitionFinished() {
22018 synchronized (ActivityManagerService.this) {
22019 mStackSupervisor.notifyAppTransitionDone();
22024 public void notifyAppTransitionCancelled() {
22025 synchronized (ActivityManagerService.this) {
22026 mStackSupervisor.notifyAppTransitionDone();
22031 public List<IBinder> getTopVisibleActivities() {
22032 synchronized (ActivityManagerService.this) {
22033 return mStackSupervisor.getTopVisibleActivities();
22038 public void notifyDockedStackMinimizedChanged(boolean minimized) {
22039 synchronized (ActivityManagerService.this) {
22040 mStackSupervisor.setDockedStackMinimized(minimized);
22045 public void killForegroundAppsForUser(int userHandle) {
22046 synchronized (ActivityManagerService.this) {
22047 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22048 final int NP = mProcessNames.getMap().size();
22049 for (int ip = 0; ip < NP; ip++) {
22050 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22051 final int NA = apps.size();
22052 for (int ia = 0; ia < NA; ia++) {
22053 final ProcessRecord app = apps.valueAt(ia);
22054 if (app.persistent) {
22055 // We don't kill persistent processes.
22060 } else if (app.userId == userHandle && app.foregroundActivities) {
22061 app.removed = true;
22067 final int N = procs.size();
22068 for (int i = 0; i < N; i++) {
22069 removeProcessLocked(procs.get(i), false, true, "kill all fg");
22075 public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22076 if (!(target instanceof PendingIntentRecord)) {
22077 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22080 ((PendingIntentRecord) target).setWhitelistDuration(duration);
22084 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22086 Preconditions.checkNotNull(values, "Configuration must not be null");
22087 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22088 synchronized (ActivityManagerService.this) {
22089 updateConfigurationLocked(values, null, false, true, userId,
22090 false /* deferResume */);
22095 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22097 Preconditions.checkNotNull(intents, "intents");
22098 final String[] resolvedTypes = new String[intents.length];
22099 for (int i = 0; i < intents.length; i++) {
22100 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22103 // UID of the package on user userId.
22104 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22105 // packageUid may not be initialized.
22106 int packageUid = 0;
22108 packageUid = AppGlobals.getPackageManager().getPackageUid(
22109 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22110 } catch (RemoteException e) {
22111 // Shouldn't happen.
22114 synchronized (ActivityManagerService.this) {
22115 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22116 /*resultTo*/ null, bOptions, userId);
22121 public int getUidProcessState(int uid) {
22122 return getUidState(uid);
22126 private final class SleepTokenImpl extends SleepToken {
22127 private final String mTag;
22128 private final long mAcquireTime;
22130 public SleepTokenImpl(String tag) {
22132 mAcquireTime = SystemClock.uptimeMillis();
22136 public void release() {
22137 synchronized (ActivityManagerService.this) {
22138 if (mSleepTokens.remove(this)) {
22139 updateSleepIfNeededLocked();
22145 public String toString() {
22146 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22151 * An implementation of IAppTask, that allows an app to manage its own tasks via
22152 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
22153 * only the process that calls getAppTasks() can call the AppTask methods.
22155 class AppTaskImpl extends IAppTask.Stub {
22156 private int mTaskId;
22157 private int mCallingUid;
22159 public AppTaskImpl(int taskId, int callingUid) {
22161 mCallingUid = callingUid;
22164 private void checkCaller() {
22165 if (mCallingUid != Binder.getCallingUid()) {
22166 throw new SecurityException("Caller " + mCallingUid
22167 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22172 public void finishAndRemoveTask() {
22175 synchronized (ActivityManagerService.this) {
22176 long origId = Binder.clearCallingIdentity();
22178 // We remove the task from recents to preserve backwards
22179 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22180 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22183 Binder.restoreCallingIdentity(origId);
22189 public ActivityManager.RecentTaskInfo getTaskInfo() {
22192 synchronized (ActivityManagerService.this) {
22193 long origId = Binder.clearCallingIdentity();
22195 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22197 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22199 return createRecentTaskInfoFromTaskRecord(tr);
22201 Binder.restoreCallingIdentity(origId);
22207 public void moveToFront() {
22209 // Will bring task to front if it already has a root activity.
22210 final long origId = Binder.clearCallingIdentity();
22212 synchronized (this) {
22213 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22216 Binder.restoreCallingIdentity(origId);
22221 public int startActivity(IBinder whoThread, String callingPackage,
22222 Intent intent, String resolvedType, Bundle bOptions) {
22225 int callingUser = UserHandle.getCallingUserId();
22227 IApplicationThread appThread;
22228 synchronized (ActivityManagerService.this) {
22229 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22231 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22233 appThread = ApplicationThreadNative.asInterface(whoThread);
22234 if (appThread == null) {
22235 throw new IllegalArgumentException("Bad app thread " + appThread);
22238 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22239 resolvedType, null, null, null, null, 0, 0, null, null,
22240 null, bOptions, false, callingUser, null, tr);
22244 public void setExcludeFromRecents(boolean exclude) {
22247 synchronized (ActivityManagerService.this) {
22248 long origId = Binder.clearCallingIdentity();
22250 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22252 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22254 Intent intent = tr.getBaseIntent();
22256 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22258 intent.setFlags(intent.getFlags()
22259 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22262 Binder.restoreCallingIdentity(origId);
22269 * Kill processes for the user with id userId and that depend on the package named packageName
22272 public void killPackageDependents(String packageName, int userId) {
22273 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22274 if (packageName == null) {
22275 throw new NullPointerException(
22276 "Cannot kill the dependents of a package without its name.");
22279 long callingId = Binder.clearCallingIdentity();
22280 IPackageManager pm = AppGlobals.getPackageManager();
22283 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22284 } catch (RemoteException e) {
22286 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22287 throw new IllegalArgumentException(
22288 "Cannot kill dependents of non-existing package " + packageName);
22291 synchronized(this) {
22292 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22293 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22294 "dep: " + packageName);
22297 Binder.restoreCallingIdentity(callingId);
22302 public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22303 final int userId = intent.getCreatorUserHandle().getIdentifier();
22304 if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22307 IIntentSender target = intent.getTarget();
22308 if (!(target instanceof PendingIntentRecord)) {
22311 final PendingIntentRecord record = (PendingIntentRecord) target;
22312 final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22313 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22314 // For direct boot aware activities, they can be shown without triggering a work challenge
22315 // before the profile user is unlocked.
22316 return rInfo != null && rInfo.activityInfo != null;