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, callingPackage, intent,
4750 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4751 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) {
4772 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4773 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4774 // TODO: Switch to user app stacks here.
4775 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4776 resultTo, bOptions, userId);
4781 public void reportActivityFullyDrawn(IBinder token) {
4782 synchronized (this) {
4783 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4787 r.reportFullyDrawnLocked();
4792 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4793 synchronized (this) {
4794 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4798 TaskRecord task = r.task;
4799 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4800 // Fixed screen orientation isn't supported when activities aren't in full screen
4804 final long origId = Binder.clearCallingIdentity();
4805 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4806 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4807 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4808 if (config != null) {
4809 r.frozenBeforeDestroy = true;
4810 if (!updateConfigurationLocked(config, r, false)) {
4811 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4814 Binder.restoreCallingIdentity(origId);
4819 public int getRequestedOrientation(IBinder token) {
4820 synchronized (this) {
4821 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4823 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4825 return mWindowManager.getAppOrientation(r.appToken);
4830 * This is the internal entry point for handling Activity.finish().
4832 * @param token The Binder token referencing the Activity we want to finish.
4833 * @param resultCode Result code, if any, from this Activity.
4834 * @param resultData Result data (Intent), if any, from this Activity.
4835 * @param finishTask Whether to finish the task associated with this Activity.
4837 * @return Returns true if the activity successfully finished, or false if it is still running.
4840 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4842 // Refuse possible leaked file descriptors
4843 if (resultData != null && resultData.hasFileDescriptors() == true) {
4844 throw new IllegalArgumentException("File descriptors passed in Intent");
4847 synchronized(this) {
4848 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4852 // Keep track of the root activity of the task before we finish it
4853 TaskRecord tr = r.task;
4854 ActivityRecord rootR = tr.getRootActivity();
4855 if (rootR == null) {
4856 Slog.w(TAG, "Finishing task with all activities already finished");
4858 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4860 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4861 mStackSupervisor.isLastLockedTask(tr)) {
4862 Slog.i(TAG, "Not finishing task in lock task mode");
4863 mStackSupervisor.showLockTaskToast();
4866 if (mController != null) {
4867 // Find the first activity that is not finishing.
4868 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4870 // ask watcher if this is allowed
4871 boolean resumeOK = true;
4873 resumeOK = mController.activityResuming(next.packageName);
4874 } catch (RemoteException e) {
4876 Watchdog.getInstance().setActivityController(null);
4880 Slog.i(TAG, "Not finishing activity because controller resumed");
4885 final long origId = Binder.clearCallingIdentity();
4888 final boolean finishWithRootActivity =
4889 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4890 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4891 || (finishWithRootActivity && r == rootR)) {
4892 // If requested, remove the task that is associated to this activity only if it
4893 // was the root activity in the task. The result code and data is ignored
4894 // because we don't support returning them across task boundaries. Also, to
4895 // keep backwards compatibility we remove the task from recents when finishing
4896 // task with root activity.
4897 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4899 Slog.i(TAG, "Removing task failed to finish activity");
4902 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4903 resultData, "app-request", true);
4905 Slog.i(TAG, "Failed to finish by app-request");
4910 Binder.restoreCallingIdentity(origId);
4916 public final void finishHeavyWeightApp() {
4917 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4918 != PackageManager.PERMISSION_GRANTED) {
4919 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4920 + Binder.getCallingPid()
4921 + ", uid=" + Binder.getCallingUid()
4922 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4924 throw new SecurityException(msg);
4927 synchronized(this) {
4928 if (mHeavyWeightProcess == null) {
4932 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4933 for (int i = 0; i < activities.size(); i++) {
4934 ActivityRecord r = activities.get(i);
4935 if (!r.finishing && r.isInStackLocked()) {
4936 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4937 null, "finish-heavy", true);
4941 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4942 mHeavyWeightProcess.userId, 0));
4943 mHeavyWeightProcess = null;
4948 public void crashApplication(int uid, int initialPid, String packageName,
4950 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4951 != PackageManager.PERMISSION_GRANTED) {
4952 String msg = "Permission Denial: crashApplication() from pid="
4953 + Binder.getCallingPid()
4954 + ", uid=" + Binder.getCallingUid()
4955 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4957 throw new SecurityException(msg);
4960 synchronized(this) {
4961 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4966 public final void finishSubActivity(IBinder token, String resultWho,
4968 synchronized(this) {
4969 final long origId = Binder.clearCallingIdentity();
4970 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4972 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4974 Binder.restoreCallingIdentity(origId);
4979 public boolean finishActivityAffinity(IBinder token) {
4980 synchronized(this) {
4981 final long origId = Binder.clearCallingIdentity();
4983 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4988 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4990 final TaskRecord task = r.task;
4991 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4992 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4993 mStackSupervisor.showLockTaskToast();
4996 return task.stack.finishActivityAffinityLocked(r);
4998 Binder.restoreCallingIdentity(origId);
5004 public void finishVoiceTask(IVoiceInteractionSession session) {
5005 synchronized (this) {
5006 final long origId = Binder.clearCallingIdentity();
5008 // TODO: VI Consider treating local voice interactions and voice tasks
5010 mStackSupervisor.finishVoiceTask(session);
5012 Binder.restoreCallingIdentity(origId);
5019 public boolean releaseActivityInstance(IBinder token) {
5020 synchronized(this) {
5021 final long origId = Binder.clearCallingIdentity();
5023 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5027 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5029 Binder.restoreCallingIdentity(origId);
5035 public void releaseSomeActivities(IApplicationThread appInt) {
5036 synchronized(this) {
5037 final long origId = Binder.clearCallingIdentity();
5039 ProcessRecord app = getRecordForAppLocked(appInt);
5040 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5042 Binder.restoreCallingIdentity(origId);
5048 public boolean willActivityBeVisible(IBinder token) {
5049 synchronized(this) {
5050 ActivityStack stack = ActivityRecord.getStackLocked(token);
5051 if (stack != null) {
5052 return stack.willActivityBeVisibleLocked(token);
5059 public void overridePendingTransition(IBinder token, String packageName,
5060 int enterAnim, int exitAnim) {
5061 synchronized(this) {
5062 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5067 final long origId = Binder.clearCallingIdentity();
5069 if (self.state == ActivityState.RESUMED
5070 || self.state == ActivityState.PAUSING) {
5071 mWindowManager.overridePendingAppTransition(packageName,
5072 enterAnim, exitAnim, null);
5075 Binder.restoreCallingIdentity(origId);
5080 * Main function for removing an existing process from the activity manager
5081 * as a result of that process going away. Clears out all connections
5084 private final void handleAppDiedLocked(ProcessRecord app,
5085 boolean restarting, boolean allowRestart) {
5087 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5088 false /*replacingPid*/);
5089 if (!kept && !restarting) {
5090 removeLruProcessLocked(app);
5092 ProcessList.remove(pid);
5096 if (mProfileProc == app) {
5097 clearProfilerLocked();
5100 // Remove this application's activities from active lists.
5101 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5103 app.activities.clear();
5105 if (app.instrumentationClass != null) {
5106 Slog.w(TAG, "Crash of app " + app.processName
5107 + " running instrumentation " + app.instrumentationClass);
5108 Bundle info = new Bundle();
5109 info.putString("shortMsg", "Process crashed.");
5110 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5113 if (!restarting && hasVisibleActivities
5114 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5115 // If there was nothing to resume, and we are not already restarting this process, but
5116 // there is a visible activity that is hosted by the process... then make sure all
5117 // visible activities are running, taking care of restarting this process.
5118 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5122 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5123 IBinder threadBinder = thread.asBinder();
5124 // Find the application record.
5125 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5126 ProcessRecord rec = mLruProcesses.get(i);
5127 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5134 final ProcessRecord getRecordForAppLocked(
5135 IApplicationThread thread) {
5136 if (thread == null) {
5140 int appIndex = getLRURecordIndexForAppLocked(thread);
5141 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5144 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5145 // If there are no longer any background processes running,
5146 // and the app that died was not running instrumentation,
5147 // then tell everyone we are now low on memory.
5148 boolean haveBg = false;
5149 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5150 ProcessRecord rec = mLruProcesses.get(i);
5151 if (rec.thread != null
5152 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5159 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5161 long now = SystemClock.uptimeMillis();
5162 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5165 mLastMemUsageReportTime = now;
5168 final ArrayList<ProcessMemInfo> memInfos
5169 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5170 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5171 long now = SystemClock.uptimeMillis();
5172 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5173 ProcessRecord rec = mLruProcesses.get(i);
5174 if (rec == dyingProc || rec.thread == null) {
5178 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5179 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5181 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5182 // The low memory report is overriding any current
5183 // state for a GC request. Make sure to do
5184 // heavy/important/visible/foreground processes first.
5185 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5186 rec.lastRequestedGc = 0;
5188 rec.lastRequestedGc = rec.lastLowMemory;
5190 rec.reportLowMemory = true;
5191 rec.lastLowMemory = now;
5192 mProcessesToGc.remove(rec);
5193 addProcessToGcListLocked(rec);
5197 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5198 mHandler.sendMessage(msg);
5200 scheduleAppGcsLocked();
5204 final void appDiedLocked(ProcessRecord app) {
5205 appDiedLocked(app, app.pid, app.thread, false);
5208 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5209 boolean fromBinderDied) {
5210 // First check if this ProcessRecord is actually active for the pid.
5211 synchronized (mPidsSelfLocked) {
5212 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5213 if (curProc != app) {
5214 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5219 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5220 synchronized (stats) {
5221 stats.noteProcessDiedLocked(app.info.uid, pid);
5225 if (!fromBinderDied) {
5226 Process.killProcessQuiet(pid);
5228 killProcessGroup(app.uid, pid);
5232 // Clean up already done if the process has been re-started.
5233 if (app.pid == pid && app.thread != null &&
5234 app.thread.asBinder() == thread.asBinder()) {
5235 boolean doLowMem = app.instrumentationClass == null;
5236 boolean doOomAdj = doLowMem;
5237 if (!app.killedByAm) {
5238 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5240 mAllowLowerMemLevel = true;
5242 // Note that we always want to do oom adj to update our state with the
5243 // new number of procs.
5244 mAllowLowerMemLevel = false;
5247 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5248 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5249 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5250 handleAppDiedLocked(app, false, true);
5253 updateOomAdjLocked();
5256 doLowMemReportIfNeededLocked(app);
5258 } else if (app.pid != pid) {
5259 // A new process has already been started.
5260 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5261 + ") has died and restarted (pid " + app.pid + ").");
5262 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5263 } else if (DEBUG_PROCESSES) {
5264 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5265 + thread.asBinder());
5270 * If a stack trace dump file is configured, dump process stack traces.
5271 * @param clearTraces causes the dump file to be erased prior to the new
5272 * traces being written, if true; when false, the new traces will be
5273 * appended to any existing file content.
5274 * @param firstPids of dalvik VM processes to dump stack traces for first
5275 * @param lastPids of dalvik VM processes to dump stack traces for last
5276 * @param nativeProcs optional list of native process names to dump stack crawls
5277 * @return file containing stack traces, or null if no dump file is configured
5279 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5280 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5281 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5282 if (tracesPath == null || tracesPath.length() == 0) {
5286 File tracesFile = new File(tracesPath);
5288 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5289 tracesFile.createNewFile();
5290 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5291 } catch (IOException e) {
5292 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5296 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5300 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5301 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5302 // Use a FileObserver to detect when traces finish writing.
5303 // The order of traces is considered important to maintain for legibility.
5304 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5306 public synchronized void onEvent(int event, String path) { notify(); }
5310 observer.startWatching();
5312 // First collect all of the stacks of the most important pids.
5313 if (firstPids != null) {
5315 int num = firstPids.size();
5316 for (int i = 0; i < num; i++) {
5317 synchronized (observer) {
5318 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5319 + firstPids.get(i));
5320 final long sime = SystemClock.elapsedRealtime();
5321 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5322 observer.wait(1000); // Wait for write-close, give up after 1 sec
5323 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5324 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5327 } catch (InterruptedException e) {
5332 // Next collect the stacks of the native pids
5333 if (nativeProcs != null) {
5334 int[] pids = Process.getPidsForCommands(nativeProcs);
5336 for (int pid : pids) {
5337 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5338 final long sime = SystemClock.elapsedRealtime();
5339 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5340 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5341 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5346 // Lastly, measure CPU usage.
5347 if (processCpuTracker != null) {
5348 processCpuTracker.init();
5350 processCpuTracker.update();
5352 synchronized (processCpuTracker) {
5353 processCpuTracker.wait(500); // measure over 1/2 second.
5355 } catch (InterruptedException e) {
5357 processCpuTracker.update();
5359 // We'll take the stack crawls of just the top apps using CPU.
5360 final int N = processCpuTracker.countWorkingStats();
5362 for (int i=0; i<N && numProcs<5; i++) {
5363 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5364 if (lastPids.indexOfKey(stats.pid) >= 0) {
5367 synchronized (observer) {
5368 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5370 final long stime = SystemClock.elapsedRealtime();
5371 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5372 observer.wait(1000); // Wait for write-close, give up after 1 sec
5373 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5374 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5376 } catch (InterruptedException e) {
5379 } else if (DEBUG_ANR) {
5380 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5386 observer.stopWatching();
5390 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5391 if (true || IS_USER_BUILD) {
5394 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5395 if (tracesPath == null || tracesPath.length() == 0) {
5399 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5400 StrictMode.allowThreadDiskWrites();
5402 final File tracesFile = new File(tracesPath);
5403 final File tracesDir = tracesFile.getParentFile();
5404 final File tracesTmp = new File(tracesDir, "__tmp__");
5406 if (tracesFile.exists()) {
5408 tracesFile.renameTo(tracesTmp);
5410 StringBuilder sb = new StringBuilder();
5411 Time tobj = new Time();
5412 tobj.set(System.currentTimeMillis());
5413 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5415 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5416 sb.append(" since ");
5418 FileOutputStream fos = new FileOutputStream(tracesFile);
5419 fos.write(sb.toString().getBytes());
5421 fos.write("\n*** No application process!".getBytes());
5424 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5425 } catch (IOException e) {
5426 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5431 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5432 firstPids.add(app.pid);
5433 dumpStackTraces(tracesPath, firstPids, null, null, null);
5436 File lastTracesFile = null;
5437 File curTracesFile = null;
5438 for (int i=9; i>=0; i--) {
5439 String name = String.format(Locale.US, "slow%02d.txt", i);
5440 curTracesFile = new File(tracesDir, name);
5441 if (curTracesFile.exists()) {
5442 if (lastTracesFile != null) {
5443 curTracesFile.renameTo(lastTracesFile);
5445 curTracesFile.delete();
5448 lastTracesFile = curTracesFile;
5450 tracesFile.renameTo(curTracesFile);
5451 if (tracesTmp.exists()) {
5452 tracesTmp.renameTo(tracesFile);
5455 StrictMode.setThreadPolicy(oldPolicy);
5459 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5460 if (!mLaunchWarningShown) {
5461 mLaunchWarningShown = true;
5462 mUiHandler.post(new Runnable() {
5465 synchronized (ActivityManagerService.this) {
5466 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5468 mUiHandler.postDelayed(new Runnable() {
5471 synchronized (ActivityManagerService.this) {
5473 mLaunchWarningShown = false;
5484 public boolean clearApplicationUserData(final String packageName,
5485 final IPackageDataObserver observer, int userId) {
5486 enforceNotIsolatedCaller("clearApplicationUserData");
5487 int uid = Binder.getCallingUid();
5488 int pid = Binder.getCallingPid();
5489 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5490 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5493 long callingId = Binder.clearCallingIdentity();
5495 IPackageManager pm = AppGlobals.getPackageManager();
5497 synchronized(this) {
5498 if (getPackageManagerInternalLocked().isPackageDataProtected(
5499 userId, packageName)) {
5500 throw new SecurityException(
5501 "Cannot clear data for a protected package: " + packageName);
5505 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5506 } catch (RemoteException e) {
5509 Slog.w(TAG, "Invalid packageName: " + packageName);
5510 if (observer != null) {
5512 observer.onRemoveCompleted(packageName, false);
5513 } catch (RemoteException e) {
5514 Slog.i(TAG, "Observer no longer exists.");
5519 if (uid == pkgUid || checkComponentPermission(
5520 android.Manifest.permission.CLEAR_APP_USER_DATA,
5522 == PackageManager.PERMISSION_GRANTED) {
5523 forceStopPackageLocked(packageName, pkgUid, "clear data");
5525 throw new SecurityException("PID " + pid + " does not have permission "
5526 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5527 + " of package " + packageName);
5530 // Remove all tasks match the cleared application package and user
5531 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5532 final TaskRecord tr = mRecentTasks.get(i);
5533 final String taskPackageName =
5534 tr.getBaseIntent().getComponent().getPackageName();
5535 if (tr.userId != userId) continue;
5536 if (!taskPackageName.equals(packageName)) continue;
5537 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5541 final int pkgUidF = pkgUid;
5542 final int userIdF = userId;
5543 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5545 public void onRemoveCompleted(String packageName, boolean succeeded)
5546 throws RemoteException {
5547 synchronized (ActivityManagerService.this) {
5548 finishForceStopPackageLocked(packageName, pkgUidF);
5551 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5552 Uri.fromParts("package", packageName, null));
5553 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5554 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5555 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5556 null, null, 0, null, null, null, null, false, false, userIdF);
5558 if (observer != null) {
5559 observer.onRemoveCompleted(packageName, succeeded);
5565 // Clear application user data
5566 pm.clearApplicationUserData(packageName, localObserver, userId);
5568 synchronized(this) {
5569 // Remove all permissions granted from/to this package
5570 removeUriPermissionsForPackageLocked(packageName, userId, true);
5573 // Remove all zen rules created by this package; revoke it's zen access.
5574 INotificationManager inm = NotificationManager.getService();
5575 inm.removeAutomaticZenRules(packageName);
5576 inm.setNotificationPolicyAccessGranted(packageName, false);
5578 } catch (RemoteException e) {
5581 Binder.restoreCallingIdentity(callingId);
5587 public void killBackgroundProcesses(final String packageName, int userId) {
5588 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5589 != PackageManager.PERMISSION_GRANTED &&
5590 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5591 != PackageManager.PERMISSION_GRANTED) {
5592 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5593 + Binder.getCallingPid()
5594 + ", uid=" + Binder.getCallingUid()
5595 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5597 throw new SecurityException(msg);
5600 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5601 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5602 long callingId = Binder.clearCallingIdentity();
5604 IPackageManager pm = AppGlobals.getPackageManager();
5605 synchronized(this) {
5608 appId = UserHandle.getAppId(
5609 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5610 } catch (RemoteException e) {
5613 Slog.w(TAG, "Invalid packageName: " + packageName);
5616 killPackageProcessesLocked(packageName, appId, userId,
5617 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5620 Binder.restoreCallingIdentity(callingId);
5625 public void killAllBackgroundProcesses() {
5626 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5627 != PackageManager.PERMISSION_GRANTED) {
5628 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5629 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5630 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5632 throw new SecurityException(msg);
5635 final long callingId = Binder.clearCallingIdentity();
5637 synchronized (this) {
5638 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5639 final int NP = mProcessNames.getMap().size();
5640 for (int ip = 0; ip < NP; ip++) {
5641 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5642 final int NA = apps.size();
5643 for (int ia = 0; ia < NA; ia++) {
5644 final ProcessRecord app = apps.valueAt(ia);
5645 if (app.persistent) {
5646 // We don't kill persistent processes.
5651 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5658 final int N = procs.size();
5659 for (int i = 0; i < N; i++) {
5660 removeProcessLocked(procs.get(i), false, true, "kill all background");
5663 mAllowLowerMemLevel = true;
5665 updateOomAdjLocked();
5666 doLowMemReportIfNeededLocked(null);
5669 Binder.restoreCallingIdentity(callingId);
5674 * Kills all background processes, except those matching any of the
5675 * specified properties.
5677 * @param minTargetSdk the target SDK version at or above which to preserve
5678 * processes, or {@code -1} to ignore the target SDK
5679 * @param maxProcState the process state at or below which to preserve
5680 * processes, or {@code -1} to ignore the process state
5682 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5683 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5684 != PackageManager.PERMISSION_GRANTED) {
5685 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5686 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5687 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5689 throw new SecurityException(msg);
5692 final long callingId = Binder.clearCallingIdentity();
5694 synchronized (this) {
5695 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5696 final int NP = mProcessNames.getMap().size();
5697 for (int ip = 0; ip < NP; ip++) {
5698 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5699 final int NA = apps.size();
5700 for (int ia = 0; ia < NA; ia++) {
5701 final ProcessRecord app = apps.valueAt(ia);
5704 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5705 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5712 final int N = procs.size();
5713 for (int i = 0; i < N; i++) {
5714 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5718 Binder.restoreCallingIdentity(callingId);
5723 public void forceStopPackage(final String packageName, int userId) {
5724 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5725 != PackageManager.PERMISSION_GRANTED) {
5726 String msg = "Permission Denial: forceStopPackage() from pid="
5727 + Binder.getCallingPid()
5728 + ", uid=" + Binder.getCallingUid()
5729 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5731 throw new SecurityException(msg);
5733 final int callingPid = Binder.getCallingPid();
5734 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5735 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5736 long callingId = Binder.clearCallingIdentity();
5738 IPackageManager pm = AppGlobals.getPackageManager();
5739 synchronized(this) {
5740 int[] users = userId == UserHandle.USER_ALL
5741 ? mUserController.getUsers() : new int[] { userId };
5742 for (int user : users) {
5745 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5747 } catch (RemoteException e) {
5750 Slog.w(TAG, "Invalid packageName: " + packageName);
5754 pm.setPackageStoppedState(packageName, true, user);
5755 } catch (RemoteException e) {
5756 } catch (IllegalArgumentException e) {
5757 Slog.w(TAG, "Failed trying to unstop package "
5758 + packageName + ": " + e);
5760 if (mUserController.isUserRunningLocked(user, 0)) {
5761 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5762 finishForceStopPackageLocked(packageName, pkgUid);
5767 Binder.restoreCallingIdentity(callingId);
5772 public void addPackageDependency(String packageName) {
5773 synchronized (this) {
5774 int callingPid = Binder.getCallingPid();
5775 if (callingPid == Process.myPid()) {
5780 synchronized (mPidsSelfLocked) {
5781 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5784 if (proc.pkgDeps == null) {
5785 proc.pkgDeps = new ArraySet<String>(1);
5787 proc.pkgDeps.add(packageName);
5793 * The pkg name and app id have to be specified.
5796 public void killApplication(String pkg, int appId, int userId, String reason) {
5800 // Make sure the uid is valid.
5802 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5805 int callerUid = Binder.getCallingUid();
5806 // Only the system server can kill an application
5807 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5808 // Post an aysnc message to kill the application
5809 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5812 Bundle bundle = new Bundle();
5813 bundle.putString("pkg", pkg);
5814 bundle.putString("reason", reason);
5816 mHandler.sendMessage(msg);
5818 throw new SecurityException(callerUid + " cannot kill pkg: " +
5824 public void closeSystemDialogs(String reason) {
5825 enforceNotIsolatedCaller("closeSystemDialogs");
5827 final int pid = Binder.getCallingPid();
5828 final int uid = Binder.getCallingUid();
5829 final long origId = Binder.clearCallingIdentity();
5831 synchronized (this) {
5832 // Only allow this from foreground processes, so that background
5833 // applications can't abuse it to prevent system UI from being shown.
5834 if (uid >= Process.FIRST_APPLICATION_UID) {
5836 synchronized (mPidsSelfLocked) {
5837 proc = mPidsSelfLocked.get(pid);
5839 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5840 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5841 + " from background process " + proc);
5845 closeSystemDialogsLocked(reason);
5848 Binder.restoreCallingIdentity(origId);
5852 void closeSystemDialogsLocked(String reason) {
5853 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5854 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5855 | Intent.FLAG_RECEIVER_FOREGROUND);
5856 if (reason != null) {
5857 intent.putExtra("reason", reason);
5859 mWindowManager.closeSystemDialogs(reason);
5861 mStackSupervisor.closeSystemDialogsLocked();
5863 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5864 AppOpsManager.OP_NONE, null, false, false,
5865 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5869 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5870 enforceNotIsolatedCaller("getProcessMemoryInfo");
5871 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5872 for (int i=pids.length-1; i>=0; i--) {
5875 synchronized (this) {
5876 synchronized (mPidsSelfLocked) {
5877 proc = mPidsSelfLocked.get(pids[i]);
5878 oomAdj = proc != null ? proc.setAdj : 0;
5881 infos[i] = new Debug.MemoryInfo();
5882 Debug.getMemoryInfo(pids[i], infos[i]);
5884 synchronized (this) {
5885 if (proc.thread != null && proc.setAdj == oomAdj) {
5886 // Record this for posterity if the process has been stable.
5887 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5888 infos[i].getTotalUss(), false, proc.pkgList);
5897 public long[] getProcessPss(int[] pids) {
5898 enforceNotIsolatedCaller("getProcessPss");
5899 long[] pss = new long[pids.length];
5900 for (int i=pids.length-1; i>=0; i--) {
5903 synchronized (this) {
5904 synchronized (mPidsSelfLocked) {
5905 proc = mPidsSelfLocked.get(pids[i]);
5906 oomAdj = proc != null ? proc.setAdj : 0;
5909 long[] tmpUss = new long[1];
5910 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5912 synchronized (this) {
5913 if (proc.thread != null && proc.setAdj == oomAdj) {
5914 // Record this for posterity if the process has been stable.
5915 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5924 public void killApplicationProcess(String processName, int uid) {
5925 if (processName == null) {
5929 int callerUid = Binder.getCallingUid();
5930 // Only the system server can kill an application
5931 if (callerUid == Process.SYSTEM_UID) {
5932 synchronized (this) {
5933 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5934 if (app != null && app.thread != null) {
5936 app.thread.scheduleSuicide();
5937 } catch (RemoteException e) {
5938 // If the other end already died, then our work here is done.
5941 Slog.w(TAG, "Process/uid not found attempting kill of "
5942 + processName + " / " + uid);
5946 throw new SecurityException(callerUid + " cannot kill app process: " +
5951 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5952 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5953 false, true, false, false, UserHandle.getUserId(uid), reason);
5956 private void finishForceStopPackageLocked(final String packageName, int uid) {
5957 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5958 Uri.fromParts("package", packageName, null));
5959 if (!mProcessesReady) {
5960 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5961 | Intent.FLAG_RECEIVER_FOREGROUND);
5963 intent.putExtra(Intent.EXTRA_UID, uid);
5964 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5965 broadcastIntentLocked(null, null, intent,
5966 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5967 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5971 private final boolean killPackageProcessesLocked(String packageName, int appId,
5972 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5973 boolean doit, boolean evenPersistent, String reason) {
5974 ArrayList<ProcessRecord> procs = new ArrayList<>();
5976 // Remove all processes this package may have touched: all with the
5977 // same UID (except for the system or root user), and all whose name
5978 // matches the package name.
5979 final int NP = mProcessNames.getMap().size();
5980 for (int ip=0; ip<NP; ip++) {
5981 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5982 final int NA = apps.size();
5983 for (int ia=0; ia<NA; ia++) {
5984 ProcessRecord app = apps.valueAt(ia);
5985 if (app.persistent && !evenPersistent) {
5986 // we don't kill persistent processes
5996 // Skip process if it doesn't meet our oom adj requirement.
5997 if (app.setAdj < minOomAdj) {
6001 // If no package is specified, we call all processes under the
6003 if (packageName == null) {
6004 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6007 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6010 // Package has been specified, we want to hit all processes
6011 // that match it. We need to qualify this by the processes
6012 // that are running under the specified app and user ID.
6014 final boolean isDep = app.pkgDeps != null
6015 && app.pkgDeps.contains(packageName);
6016 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6019 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6022 if (!app.pkgList.containsKey(packageName) && !isDep) {
6027 // Process has passed all conditions, kill it!
6036 int N = procs.size();
6037 for (int i=0; i<N; i++) {
6038 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6040 updateOomAdjLocked();
6044 private void cleanupDisabledPackageComponentsLocked(
6045 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6047 Set<String> disabledClasses = null;
6048 boolean packageDisabled = false;
6049 IPackageManager pm = AppGlobals.getPackageManager();
6051 if (changedClasses == null) {
6052 // Nothing changed...
6056 // Determine enable/disable state of the package and its components.
6057 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6058 for (int i = changedClasses.length - 1; i >= 0; i--) {
6059 final String changedClass = changedClasses[i];
6061 if (changedClass.equals(packageName)) {
6063 // Entire package setting changed
6064 enabled = pm.getApplicationEnabledSetting(packageName,
6065 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6066 } catch (Exception e) {
6067 // No such package/component; probably racing with uninstall. In any
6068 // event it means we have nothing further to do here.
6071 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6072 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6073 if (packageDisabled) {
6074 // Entire package is disabled.
6075 // No need to continue to check component states.
6076 disabledClasses = null;
6081 enabled = pm.getComponentEnabledSetting(
6082 new ComponentName(packageName, changedClass),
6083 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6084 } catch (Exception e) {
6085 // As above, probably racing with uninstall.
6088 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6089 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6090 if (disabledClasses == null) {
6091 disabledClasses = new ArraySet<>(changedClasses.length);
6093 disabledClasses.add(changedClass);
6098 if (!packageDisabled && disabledClasses == null) {
6099 // Nothing to do here...
6103 // Clean-up disabled activities.
6104 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6105 packageName, disabledClasses, true, false, userId) && mBooted) {
6106 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6107 mStackSupervisor.scheduleIdleLocked();
6110 // Clean-up disabled tasks
6111 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6113 // Clean-up disabled services.
6114 mServices.bringDownDisabledPackageServicesLocked(
6115 packageName, disabledClasses, userId, false, killProcess, true);
6117 // Clean-up disabled providers.
6118 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6119 mProviderMap.collectPackageProvidersLocked(
6120 packageName, disabledClasses, true, false, userId, providers);
6121 for (int i = providers.size() - 1; i >= 0; i--) {
6122 removeDyingProviderLocked(null, providers.get(i), true);
6125 // Clean-up disabled broadcast receivers.
6126 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6127 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6128 packageName, disabledClasses, userId, true);
6133 final boolean clearBroadcastQueueForUserLocked(int userId) {
6134 boolean didSomething = false;
6135 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6136 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6137 null, null, userId, true);
6139 return didSomething;
6142 final boolean forceStopPackageLocked(String packageName, int appId,
6143 boolean callerWillRestart, boolean purgeCache, boolean doit,
6144 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6147 if (userId == UserHandle.USER_ALL && packageName == null) {
6148 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6151 if (appId < 0 && packageName != null) {
6153 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6154 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6155 } catch (RemoteException e) {
6160 if (packageName != null) {
6161 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6162 + " user=" + userId + ": " + reason);
6164 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6167 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6170 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6171 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6172 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6174 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6175 packageName, null, doit, evenPersistent, userId)) {
6179 didSomething = true;
6182 if (mServices.bringDownDisabledPackageServicesLocked(
6183 packageName, null, userId, evenPersistent, true, doit)) {
6187 didSomething = true;
6190 if (packageName == null) {
6191 // Remove all sticky broadcasts from this user.
6192 mStickyBroadcasts.remove(userId);
6195 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6196 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6197 userId, providers)) {
6201 didSomething = true;
6203 for (i = providers.size() - 1; i >= 0; i--) {
6204 removeDyingProviderLocked(null, providers.get(i), true);
6207 // Remove transient permissions granted from/to this package/user
6208 removeUriPermissionsForPackageLocked(packageName, userId, false);
6211 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6212 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6213 packageName, null, userId, doit);
6217 if (packageName == null || uninstalling) {
6218 // Remove pending intents. For now we only do this when force
6219 // stopping users, because we have some problems when doing this
6220 // for packages -- app widgets are not currently cleaned up for
6221 // such packages, so they can be left with bad pending intents.
6222 if (mIntentSenderRecords.size() > 0) {
6223 Iterator<WeakReference<PendingIntentRecord>> it
6224 = mIntentSenderRecords.values().iterator();
6225 while (it.hasNext()) {
6226 WeakReference<PendingIntentRecord> wpir = it.next();
6231 PendingIntentRecord pir = wpir.get();
6236 if (packageName == null) {
6237 // Stopping user, remove all objects for the user.
6238 if (pir.key.userId != userId) {
6239 // Not the same user, skip it.
6243 if (UserHandle.getAppId(pir.uid) != appId) {
6244 // Different app id, skip it.
6247 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6248 // Different user, skip it.
6251 if (!pir.key.packageName.equals(packageName)) {
6252 // Different package, skip it.
6259 didSomething = true;
6261 pir.canceled = true;
6262 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6263 pir.key.activity.pendingResults.remove(pir.ref);
6270 if (purgeCache && packageName != null) {
6271 AttributeCache ac = AttributeCache.instance();
6273 ac.removePackage(packageName);
6277 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6278 mStackSupervisor.scheduleIdleLocked();
6282 return didSomething;
6285 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6286 return removeProcessNameLocked(name, uid, null);
6289 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6290 final ProcessRecord expecting) {
6291 ProcessRecord old = mProcessNames.get(name, uid);
6292 // Only actually remove when the currently recorded value matches the
6293 // record that we expected; if it doesn't match then we raced with a
6294 // newly created process and we don't want to destroy the new one.
6295 if ((expecting == null) || (old == expecting)) {
6296 mProcessNames.remove(name, uid);
6298 if (old != null && old.uidRecord != null) {
6299 old.uidRecord.numProcs--;
6300 if (old.uidRecord.numProcs == 0) {
6301 // No more processes using this uid, tell clients it is gone.
6302 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6303 "No more processes in " + old.uidRecord);
6304 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6305 mActiveUids.remove(uid);
6306 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6308 old.uidRecord = null;
6310 mIsolatedProcesses.remove(uid);
6314 private final void addProcessNameLocked(ProcessRecord proc) {
6315 // We shouldn't already have a process under this name, but just in case we
6316 // need to clean up whatever may be there now.
6317 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6318 if (old == proc && proc.persistent) {
6319 // We are re-adding a persistent process. Whatevs! Just leave it there.
6320 Slog.w(TAG, "Re-adding persistent process " + proc);
6321 } else if (old != null) {
6322 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6324 UidRecord uidRec = mActiveUids.get(proc.uid);
6325 if (uidRec == null) {
6326 uidRec = new UidRecord(proc.uid);
6327 // This is the first appearance of the uid, report it now!
6328 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6329 "Creating new process uid: " + uidRec);
6330 mActiveUids.put(proc.uid, uidRec);
6331 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6332 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6334 proc.uidRecord = uidRec;
6336 // Reset render thread tid if it was already set, so new process can set it again.
6337 proc.renderThreadTid = 0;
6339 mProcessNames.put(proc.processName, proc.uid, proc);
6340 if (proc.isolated) {
6341 mIsolatedProcesses.put(proc.uid, proc);
6345 boolean removeProcessLocked(ProcessRecord app,
6346 boolean callerWillRestart, boolean allowRestart, String reason) {
6347 final String name = app.processName;
6348 final int uid = app.uid;
6349 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6350 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6352 ProcessRecord old = mProcessNames.get(name, uid);
6354 // This process is no longer active, so nothing to do.
6355 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6358 removeProcessNameLocked(name, uid);
6359 if (mHeavyWeightProcess == app) {
6360 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6361 mHeavyWeightProcess.userId, 0));
6362 mHeavyWeightProcess = null;
6364 boolean needRestart = false;
6365 if (app.pid > 0 && app.pid != MY_PID) {
6367 synchronized (mPidsSelfLocked) {
6368 mPidsSelfLocked.remove(pid);
6369 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6371 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6373 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6375 boolean willRestart = false;
6376 if (app.persistent && !app.isolated) {
6377 if (!callerWillRestart) {
6383 app.kill(reason, true);
6384 handleAppDiedLocked(app, willRestart, allowRestart);
6386 removeLruProcessLocked(app);
6387 addAppLocked(app.info, false, null /* ABI override */);
6390 mRemovedProcesses.add(app);
6396 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6397 cleanupAppInLaunchingProvidersLocked(app, true);
6398 removeProcessLocked(app, false, true, "timeout publishing content providers");
6401 private final void processStartTimedOutLocked(ProcessRecord app) {
6402 final int pid = app.pid;
6403 boolean gone = false;
6404 synchronized (mPidsSelfLocked) {
6405 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6406 if (knownApp != null && knownApp.thread == null) {
6407 mPidsSelfLocked.remove(pid);
6413 Slog.w(TAG, "Process " + app + " failed to attach");
6414 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6415 pid, app.uid, app.processName);
6416 removeProcessNameLocked(app.processName, app.uid);
6417 if (mHeavyWeightProcess == app) {
6418 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6419 mHeavyWeightProcess.userId, 0));
6420 mHeavyWeightProcess = null;
6422 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6424 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6426 // Take care of any launching providers waiting for this process.
6427 cleanupAppInLaunchingProvidersLocked(app, true);
6428 // Take care of any services that are waiting for the process.
6429 mServices.processStartTimedOutLocked(app);
6430 app.kill("start timeout", true);
6431 removeLruProcessLocked(app);
6432 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6433 Slog.w(TAG, "Unattached app died before backup, skipping");
6435 IBackupManager bm = IBackupManager.Stub.asInterface(
6436 ServiceManager.getService(Context.BACKUP_SERVICE));
6437 bm.agentDisconnected(app.info.packageName);
6438 } catch (RemoteException e) {
6439 // Can't happen; the backup manager is local
6442 if (isPendingBroadcastProcessLocked(pid)) {
6443 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6444 skipPendingBroadcastLocked(pid);
6447 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6451 private final boolean attachApplicationLocked(IApplicationThread thread,
6454 // Find the application record that is being attached... either via
6455 // the pid if we are running in multiple processes, or just pull the
6456 // next app record if we are emulating process with anonymous threads.
6458 long startTime = SystemClock.uptimeMillis();
6459 if (pid != MY_PID && pid >= 0) {
6460 synchronized (mPidsSelfLocked) {
6461 app = mPidsSelfLocked.get(pid);
6468 Slog.w(TAG, "No pending application record for pid " + pid
6469 + " (IApplicationThread " + thread + "); dropping process");
6470 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6471 if (pid > 0 && pid != MY_PID) {
6472 Process.killProcessQuiet(pid);
6473 //TODO: killProcessGroup(app.info.uid, pid);
6476 thread.scheduleExit();
6477 } catch (Exception e) {
6478 // Ignore exceptions.
6484 // If this application record is still attached to a previous
6485 // process, clean it up now.
6486 if (app.thread != null) {
6487 handleAppDiedLocked(app, true, true);
6490 // Tell the process all about itself.
6492 if (DEBUG_ALL) Slog.v(
6493 TAG, "Binding process pid " + pid + " to record " + app);
6495 final String processName = app.processName;
6497 AppDeathRecipient adr = new AppDeathRecipient(
6499 thread.asBinder().linkToDeath(adr, 0);
6500 app.deathRecipient = adr;
6501 } catch (RemoteException e) {
6502 app.resetPackageList(mProcessStats);
6503 startProcessLocked(app, "link fail", processName);
6507 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6509 app.makeActive(thread, mProcessStats);
6510 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6511 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6512 app.forcingToForeground = null;
6513 updateProcessForegroundLocked(app, false, false);
6514 app.hasShownUi = false;
6515 app.debugging = false;
6517 app.killedByAm = false;
6519 // We carefully use the same state that PackageManager uses for
6520 // filtering, since we use this flag to decide if we need to install
6521 // providers when user is unlocked later
6522 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6524 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6526 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6527 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6529 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6530 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6532 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6535 checkTime(startTime, "attachApplicationLocked: before bindApplication");
6538 Slog.i(TAG, "Launching preboot mode app: " + app);
6541 if (DEBUG_ALL) Slog.v(
6542 TAG, "New app record " + app
6543 + " thread=" + thread.asBinder() + " pid=" + pid);
6545 int testMode = IApplicationThread.DEBUG_OFF;
6546 if (mDebugApp != null && mDebugApp.equals(processName)) {
6547 testMode = mWaitForDebugger
6548 ? IApplicationThread.DEBUG_WAIT
6549 : IApplicationThread.DEBUG_ON;
6550 app.debugging = true;
6551 if (mDebugTransient) {
6552 mDebugApp = mOrigDebugApp;
6553 mWaitForDebugger = mOrigWaitForDebugger;
6556 String profileFile = app.instrumentationProfileFile;
6557 ParcelFileDescriptor profileFd = null;
6558 int samplingInterval = 0;
6559 boolean profileAutoStop = false;
6560 if (mProfileApp != null && mProfileApp.equals(processName)) {
6562 profileFile = mProfileFile;
6563 profileFd = mProfileFd;
6564 samplingInterval = mSamplingInterval;
6565 profileAutoStop = mAutoStopProfiler;
6567 boolean enableTrackAllocation = false;
6568 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6569 enableTrackAllocation = true;
6570 mTrackAllocationApp = null;
6573 // If the app is being launched for restore or full backup, set it up specially
6574 boolean isRestrictedBackupMode = false;
6575 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6576 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6577 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6578 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6579 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6582 if (app.instrumentationClass != null) {
6583 notifyPackageUse(app.instrumentationClass.getPackageName(),
6584 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6586 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6587 + processName + " with config " + mConfiguration);
6588 ApplicationInfo appInfo = app.instrumentationInfo != null
6589 ? app.instrumentationInfo : app.info;
6590 app.compat = compatibilityInfoForPackageLocked(appInfo);
6591 if (profileFd != null) {
6592 profileFd = profileFd.dup();
6594 ProfilerInfo profilerInfo = profileFile == null ? null
6595 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6596 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6597 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6598 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6599 app.instrumentationUiAutomationConnection, testMode,
6600 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6601 isRestrictedBackupMode || !normalMode, app.persistent,
6602 new Configuration(mConfiguration), app.compat,
6603 getCommonServicesLocked(app.isolated),
6604 mCoreSettingsObserver.getCoreSettingsLocked());
6605 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6606 updateLruProcessLocked(app, false, null);
6607 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6608 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6609 } catch (Exception e) {
6610 // todo: Yikes! What should we do? For now we will try to
6611 // start another process, but that could easily get us in
6612 // an infinite loop of restarting processes...
6613 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6615 app.resetPackageList(mProcessStats);
6616 app.unlinkDeathRecipient();
6617 startProcessLocked(app, "bind fail", processName);
6621 // Remove this record from the list of starting applications.
6622 mPersistentStartingProcesses.remove(app);
6623 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6624 "Attach application locked removing on hold: " + app);
6625 mProcessesOnHold.remove(app);
6627 boolean badApp = false;
6628 boolean didSomething = false;
6630 // See if the top visible activity is waiting to run in this process...
6633 if (mStackSupervisor.attachApplicationLocked(app)) {
6634 didSomething = true;
6636 } catch (Exception e) {
6637 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6642 // Find any services that should be running in this process...
6645 didSomething |= mServices.attachApplicationLocked(app, processName);
6646 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6647 } catch (Exception e) {
6648 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6653 // Check if a next-broadcast receiver is in this process...
6654 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6656 didSomething |= sendPendingBroadcastsLocked(app);
6657 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6658 } catch (Exception e) {
6659 // If the app died trying to launch the receiver we declare it 'bad'
6660 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6665 // Check whether the next backup agent is in this process...
6666 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6667 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6668 "New app is backup target, launching agent for " + app);
6669 notifyPackageUse(mBackupTarget.appInfo.packageName,
6670 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6672 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6673 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6674 mBackupTarget.backupMode);
6675 } catch (Exception e) {
6676 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6682 app.kill("error during init", true);
6683 handleAppDiedLocked(app, false, true);
6687 if (!didSomething) {
6688 updateOomAdjLocked();
6689 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6696 public final void attachApplication(IApplicationThread thread) {
6697 synchronized (this) {
6698 int callingPid = Binder.getCallingPid();
6699 final long origId = Binder.clearCallingIdentity();
6700 attachApplicationLocked(thread, callingPid);
6701 Binder.restoreCallingIdentity(origId);
6706 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6707 final long origId = Binder.clearCallingIdentity();
6708 synchronized (this) {
6709 ActivityStack stack = ActivityRecord.getStackLocked(token);
6710 if (stack != null) {
6712 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6713 if (stopProfiling) {
6714 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6717 } catch (IOException e) {
6719 clearProfilerLocked();
6724 Binder.restoreCallingIdentity(origId);
6727 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6728 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6729 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6732 void enableScreenAfterBoot() {
6733 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6734 SystemClock.uptimeMillis());
6735 mWindowManager.enableScreenAfterBoot();
6737 synchronized (this) {
6738 updateEventDispatchingLocked();
6743 public void showBootMessage(final CharSequence msg, final boolean always) {
6744 if (Binder.getCallingUid() != Process.myUid()) {
6745 throw new SecurityException();
6747 mWindowManager.showBootMessage(msg, always);
6751 public void keyguardWaitingForActivityDrawn() {
6752 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6753 final long token = Binder.clearCallingIdentity();
6755 synchronized (this) {
6756 if (DEBUG_LOCKSCREEN) logLockScreen("");
6757 mWindowManager.keyguardWaitingForActivityDrawn();
6758 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6759 mLockScreenShown = LOCK_SCREEN_LEAVING;
6760 updateSleepIfNeededLocked();
6764 Binder.restoreCallingIdentity(token);
6769 public void keyguardGoingAway(int flags) {
6770 enforceNotIsolatedCaller("keyguardGoingAway");
6771 final long token = Binder.clearCallingIdentity();
6773 synchronized (this) {
6774 if (DEBUG_LOCKSCREEN) logLockScreen("");
6775 mWindowManager.keyguardGoingAway(flags);
6776 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6777 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6778 updateSleepIfNeededLocked();
6780 // Some stack visibility might change (e.g. docked stack)
6781 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6785 Binder.restoreCallingIdentity(token);
6789 final void finishBooting() {
6790 synchronized (this) {
6791 if (!mBootAnimationComplete) {
6792 mCallFinishBooting = true;
6795 mCallFinishBooting = false;
6798 ArraySet<String> completedIsas = new ArraySet<String>();
6799 for (String abi : Build.SUPPORTED_ABIS) {
6800 Process.establishZygoteConnectionForAbi(abi);
6801 final String instructionSet = VMRuntime.getInstructionSet(abi);
6802 if (!completedIsas.contains(instructionSet)) {
6804 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6805 } catch (InstallerException e) {
6806 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6807 e.getMessage() +")");
6809 completedIsas.add(instructionSet);
6813 IntentFilter pkgFilter = new IntentFilter();
6814 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6815 pkgFilter.addDataScheme("package");
6816 mContext.registerReceiver(new BroadcastReceiver() {
6818 public void onReceive(Context context, Intent intent) {
6819 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6821 for (String pkg : pkgs) {
6822 synchronized (ActivityManagerService.this) {
6823 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6824 0, "query restart")) {
6825 setResultCode(Activity.RESULT_OK);
6834 IntentFilter dumpheapFilter = new IntentFilter();
6835 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6836 mContext.registerReceiver(new BroadcastReceiver() {
6838 public void onReceive(Context context, Intent intent) {
6839 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6840 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6842 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6847 // Let system services know.
6848 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6850 synchronized (this) {
6851 // Ensure that any processes we had put on hold are now started
6853 final int NP = mProcessesOnHold.size();
6855 ArrayList<ProcessRecord> procs =
6856 new ArrayList<ProcessRecord>(mProcessesOnHold);
6857 for (int ip=0; ip<NP; ip++) {
6858 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6860 startProcessLocked(procs.get(ip), "on-hold", null);
6864 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6865 // Start looking for apps that are abusing wake locks.
6866 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6867 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6868 // Tell anyone interested that we are done booting!
6869 SystemProperties.set("sys.boot_completed", "1");
6871 // And trigger dev.bootcomplete if we are not showing encryption progress
6872 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6873 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6874 SystemProperties.set("dev.bootcomplete", "1");
6876 mUserController.sendBootCompletedLocked(
6877 new IIntentReceiver.Stub() {
6879 public void performReceive(Intent intent, int resultCode,
6880 String data, Bundle extras, boolean ordered,
6881 boolean sticky, int sendingUser) {
6882 synchronized (ActivityManagerService.this) {
6883 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6888 scheduleStartProfilesLocked();
6894 public void bootAnimationComplete() {
6895 final boolean callFinishBooting;
6896 synchronized (this) {
6897 callFinishBooting = mCallFinishBooting;
6898 mBootAnimationComplete = true;
6900 if (callFinishBooting) {
6901 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6903 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6907 final void ensureBootCompleted() {
6909 boolean enableScreen;
6910 synchronized (this) {
6913 enableScreen = !mBooted;
6918 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6920 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6924 enableScreenAfterBoot();
6929 public final void activityResumed(IBinder token) {
6930 final long origId = Binder.clearCallingIdentity();
6931 synchronized(this) {
6932 ActivityStack stack = ActivityRecord.getStackLocked(token);
6933 if (stack != null) {
6934 stack.activityResumedLocked(token);
6937 Binder.restoreCallingIdentity(origId);
6941 public final void activityPaused(IBinder token) {
6942 final long origId = Binder.clearCallingIdentity();
6943 synchronized(this) {
6944 ActivityStack stack = ActivityRecord.getStackLocked(token);
6945 if (stack != null) {
6946 stack.activityPausedLocked(token, false);
6949 Binder.restoreCallingIdentity(origId);
6953 public final void activityStopped(IBinder token, Bundle icicle,
6954 PersistableBundle persistentState, CharSequence description) {
6955 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6957 // Refuse possible leaked file descriptors
6958 if (icicle != null && icicle.hasFileDescriptors()) {
6959 throw new IllegalArgumentException("File descriptors passed in Bundle");
6962 final long origId = Binder.clearCallingIdentity();
6964 synchronized (this) {
6965 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6967 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6973 Binder.restoreCallingIdentity(origId);
6977 public final void activityDestroyed(IBinder token) {
6978 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6979 synchronized (this) {
6980 ActivityStack stack = ActivityRecord.getStackLocked(token);
6981 if (stack != null) {
6982 stack.activityDestroyedLocked(token, "activityDestroyed");
6988 public final void activityRelaunched(IBinder token) {
6989 final long origId = Binder.clearCallingIdentity();
6990 synchronized (this) {
6991 mStackSupervisor.activityRelaunchedLocked(token);
6993 Binder.restoreCallingIdentity(origId);
6997 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6998 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6999 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7000 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7001 synchronized (this) {
7002 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7003 if (record == null) {
7004 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7005 + "found for: " + token);
7007 record.setSizeConfigurations(horizontalSizeConfiguration,
7008 verticalSizeConfigurations, smallestSizeConfigurations);
7013 public final void backgroundResourcesReleased(IBinder token) {
7014 final long origId = Binder.clearCallingIdentity();
7016 synchronized (this) {
7017 ActivityStack stack = ActivityRecord.getStackLocked(token);
7018 if (stack != null) {
7019 stack.backgroundResourcesReleased();
7023 Binder.restoreCallingIdentity(origId);
7028 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7029 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7033 public final void notifyEnterAnimationComplete(IBinder token) {
7034 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7038 public String getCallingPackage(IBinder token) {
7039 synchronized (this) {
7040 ActivityRecord r = getCallingRecordLocked(token);
7041 return r != null ? r.info.packageName : null;
7046 public ComponentName getCallingActivity(IBinder token) {
7047 synchronized (this) {
7048 ActivityRecord r = getCallingRecordLocked(token);
7049 return r != null ? r.intent.getComponent() : null;
7053 private ActivityRecord getCallingRecordLocked(IBinder token) {
7054 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7062 public ComponentName getActivityClassForToken(IBinder token) {
7063 synchronized(this) {
7064 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7068 return r.intent.getComponent();
7073 public String getPackageForToken(IBinder token) {
7074 synchronized(this) {
7075 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7079 return r.packageName;
7084 public boolean isRootVoiceInteraction(IBinder token) {
7085 synchronized(this) {
7086 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7090 return r.rootVoiceInteraction;
7095 public IIntentSender getIntentSender(int type,
7096 String packageName, IBinder token, String resultWho,
7097 int requestCode, Intent[] intents, String[] resolvedTypes,
7098 int flags, Bundle bOptions, int userId) {
7099 enforceNotIsolatedCaller("getIntentSender");
7100 // Refuse possible leaked file descriptors
7101 if (intents != null) {
7102 if (intents.length < 1) {
7103 throw new IllegalArgumentException("Intents array length must be >= 1");
7105 for (int i=0; i<intents.length; i++) {
7106 Intent intent = intents[i];
7107 if (intent != null) {
7108 if (intent.hasFileDescriptors()) {
7109 throw new IllegalArgumentException("File descriptors passed in Intent");
7111 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7112 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7113 throw new IllegalArgumentException(
7114 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7116 intents[i] = new Intent(intent);
7119 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7120 throw new IllegalArgumentException(
7121 "Intent array length does not match resolvedTypes length");
7124 if (bOptions != null) {
7125 if (bOptions.hasFileDescriptors()) {
7126 throw new IllegalArgumentException("File descriptors passed in options");
7130 synchronized(this) {
7131 int callingUid = Binder.getCallingUid();
7132 int origUserId = userId;
7133 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7134 type == ActivityManager.INTENT_SENDER_BROADCAST,
7135 ALLOW_NON_FULL, "getIntentSender", null);
7136 if (origUserId == UserHandle.USER_CURRENT) {
7137 // We don't want to evaluate this until the pending intent is
7138 // actually executed. However, we do want to always do the
7139 // security checking for it above.
7140 userId = UserHandle.USER_CURRENT;
7143 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7144 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7145 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7146 if (!UserHandle.isSameApp(callingUid, uid)) {
7147 String msg = "Permission Denial: getIntentSender() from pid="
7148 + Binder.getCallingPid()
7149 + ", uid=" + Binder.getCallingUid()
7150 + ", (need uid=" + uid + ")"
7151 + " is not allowed to send as package " + packageName;
7153 throw new SecurityException(msg);
7157 return getIntentSenderLocked(type, packageName, callingUid, userId,
7158 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7160 } catch (RemoteException e) {
7161 throw new SecurityException(e);
7166 IIntentSender getIntentSenderLocked(int type, String packageName,
7167 int callingUid, int userId, IBinder token, String resultWho,
7168 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7170 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7171 ActivityRecord activity = null;
7172 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7173 activity = ActivityRecord.isInStackLocked(token);
7174 if (activity == null) {
7175 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7178 if (activity.finishing) {
7179 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7184 // We're going to be splicing together extras before sending, so we're
7185 // okay poking into any contained extras.
7186 if (intents != null) {
7187 for (int i = 0; i < intents.length; i++) {
7188 intents[i].setDefusable(true);
7191 Bundle.setDefusable(bOptions, true);
7193 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7194 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7195 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7196 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7197 |PendingIntent.FLAG_UPDATE_CURRENT);
7199 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7200 type, packageName, activity, resultWho,
7201 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7202 WeakReference<PendingIntentRecord> ref;
7203 ref = mIntentSenderRecords.get(key);
7204 PendingIntentRecord rec = ref != null ? ref.get() : null;
7206 if (!cancelCurrent) {
7207 if (updateCurrent) {
7208 if (rec.key.requestIntent != null) {
7209 rec.key.requestIntent.replaceExtras(intents != null ?
7210 intents[intents.length - 1] : null);
7212 if (intents != null) {
7213 intents[intents.length-1] = rec.key.requestIntent;
7214 rec.key.allIntents = intents;
7215 rec.key.allResolvedTypes = resolvedTypes;
7217 rec.key.allIntents = null;
7218 rec.key.allResolvedTypes = null;
7223 rec.canceled = true;
7224 mIntentSenderRecords.remove(key);
7229 rec = new PendingIntentRecord(this, key, callingUid);
7230 mIntentSenderRecords.put(key, rec.ref);
7231 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7232 if (activity.pendingResults == null) {
7233 activity.pendingResults
7234 = new HashSet<WeakReference<PendingIntentRecord>>();
7236 activity.pendingResults.add(rec.ref);
7242 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7243 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7244 if (target instanceof PendingIntentRecord) {
7245 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7246 finishedReceiver, requiredPermission, options);
7248 if (intent == null) {
7249 // Weird case: someone has given us their own custom IIntentSender, and now
7250 // they have someone else trying to send to it but of course this isn't
7251 // really a PendingIntent, so there is no base Intent, and the caller isn't
7252 // supplying an Intent... but we never want to dispatch a null Intent to
7253 // a receiver, so um... let's make something up.
7254 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7255 intent = new Intent(Intent.ACTION_MAIN);
7258 target.send(code, intent, resolvedType, null, requiredPermission, options);
7259 } catch (RemoteException e) {
7261 // Platform code can rely on getting a result back when the send is done, but if
7262 // this intent sender is from outside of the system we can't rely on it doing that.
7263 // So instead we don't give it the result receiver, and instead just directly
7264 // report the finish immediately.
7265 if (finishedReceiver != null) {
7267 finishedReceiver.performReceive(intent, 0,
7268 null, null, false, false, UserHandle.getCallingUserId());
7269 } catch (RemoteException e) {
7277 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7279 * <p>{@code callerUid} must be allowed to request such whitelist by calling
7280 * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7282 void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7283 if (DEBUG_WHITELISTS) {
7284 Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7285 + targetUid + ", " + duration + ")");
7287 synchronized (mPidsSelfLocked) {
7288 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7290 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7293 if (!pr.whitelistManager) {
7294 if (DEBUG_WHITELISTS) {
7295 Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7296 + callerPid + " is not allowed");
7302 final long token = Binder.clearCallingIdentity();
7304 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7305 true, "pe from uid:" + callerUid);
7307 Binder.restoreCallingIdentity(token);
7312 public void cancelIntentSender(IIntentSender sender) {
7313 if (!(sender instanceof PendingIntentRecord)) {
7316 synchronized(this) {
7317 PendingIntentRecord rec = (PendingIntentRecord)sender;
7319 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7320 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7321 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7322 String msg = "Permission Denial: cancelIntentSender() from pid="
7323 + Binder.getCallingPid()
7324 + ", uid=" + Binder.getCallingUid()
7325 + " is not allowed to cancel packges "
7326 + rec.key.packageName;
7328 throw new SecurityException(msg);
7330 } catch (RemoteException e) {
7331 throw new SecurityException(e);
7333 cancelIntentSenderLocked(rec, true);
7337 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7338 rec.canceled = true;
7339 mIntentSenderRecords.remove(rec.key);
7340 if (cleanActivity && rec.key.activity != null) {
7341 rec.key.activity.pendingResults.remove(rec.ref);
7346 public String getPackageForIntentSender(IIntentSender pendingResult) {
7347 if (!(pendingResult instanceof PendingIntentRecord)) {
7351 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7352 return res.key.packageName;
7353 } catch (ClassCastException e) {
7359 public int getUidForIntentSender(IIntentSender sender) {
7360 if (sender instanceof PendingIntentRecord) {
7362 PendingIntentRecord res = (PendingIntentRecord)sender;
7364 } catch (ClassCastException e) {
7371 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7372 if (!(pendingResult instanceof PendingIntentRecord)) {
7376 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7377 if (res.key.allIntents == null) {
7380 for (int i=0; i<res.key.allIntents.length; i++) {
7381 Intent intent = res.key.allIntents[i];
7382 if (intent.getPackage() != null && intent.getComponent() != null) {
7387 } catch (ClassCastException e) {
7393 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7394 if (!(pendingResult instanceof PendingIntentRecord)) {
7398 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7399 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7403 } catch (ClassCastException e) {
7409 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7410 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7411 "getIntentForIntentSender()");
7412 if (!(pendingResult instanceof PendingIntentRecord)) {
7416 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7417 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7418 } catch (ClassCastException e) {
7424 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7425 if (!(pendingResult instanceof PendingIntentRecord)) {
7429 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7430 synchronized (this) {
7431 return getTagForIntentSenderLocked(res, prefix);
7433 } catch (ClassCastException e) {
7438 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7439 final Intent intent = res.key.requestIntent;
7440 if (intent != null) {
7441 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7442 || res.lastTagPrefix.equals(prefix))) {
7445 res.lastTagPrefix = prefix;
7446 final StringBuilder sb = new StringBuilder(128);
7447 if (prefix != null) {
7450 if (intent.getAction() != null) {
7451 sb.append(intent.getAction());
7452 } else if (intent.getComponent() != null) {
7453 intent.getComponent().appendShortString(sb);
7457 return res.lastTag = sb.toString();
7463 public void setProcessLimit(int max) {
7464 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7465 "setProcessLimit()");
7466 synchronized (this) {
7467 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7468 mProcessLimitOverride = max;
7474 public int getProcessLimit() {
7475 synchronized (this) {
7476 return mProcessLimitOverride;
7480 void foregroundTokenDied(ForegroundToken token) {
7481 synchronized (ActivityManagerService.this) {
7482 synchronized (mPidsSelfLocked) {
7484 = mForegroundProcesses.get(token.pid);
7488 mForegroundProcesses.remove(token.pid);
7489 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7493 pr.forcingToForeground = null;
7494 updateProcessForegroundLocked(pr, false, false);
7496 updateOomAdjLocked();
7501 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7502 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7503 "setProcessForeground()");
7504 synchronized(this) {
7505 boolean changed = false;
7507 synchronized (mPidsSelfLocked) {
7508 ProcessRecord pr = mPidsSelfLocked.get(pid);
7509 if (pr == null && isForeground) {
7510 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7513 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7514 if (oldToken != null) {
7515 oldToken.token.unlinkToDeath(oldToken, 0);
7516 mForegroundProcesses.remove(pid);
7518 pr.forcingToForeground = null;
7522 if (isForeground && token != null) {
7523 ForegroundToken newToken = new ForegroundToken() {
7525 public void binderDied() {
7526 foregroundTokenDied(this);
7530 newToken.token = token;
7532 token.linkToDeath(newToken, 0);
7533 mForegroundProcesses.put(pid, newToken);
7534 pr.forcingToForeground = token;
7536 } catch (RemoteException e) {
7537 // If the process died while doing this, we will later
7538 // do the cleanup with the process death link.
7544 updateOomAdjLocked();
7550 public boolean isAppForeground(int uid) throws RemoteException {
7551 synchronized (this) {
7552 UidRecord uidRec = mActiveUids.get(uid);
7553 if (uidRec == null || uidRec.idle) {
7556 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7560 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7561 // be guarded by permission checking.
7562 int getUidState(int uid) {
7563 synchronized (this) {
7564 UidRecord uidRec = mActiveUids.get(uid);
7565 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7570 public boolean isInMultiWindowMode(IBinder token) {
7571 final long origId = Binder.clearCallingIdentity();
7573 synchronized(this) {
7574 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7578 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7579 return !r.task.mFullscreen;
7582 Binder.restoreCallingIdentity(origId);
7587 public boolean isInPictureInPictureMode(IBinder token) {
7588 final long origId = Binder.clearCallingIdentity();
7590 synchronized(this) {
7591 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7592 if (stack == null) {
7595 return stack.mStackId == PINNED_STACK_ID;
7598 Binder.restoreCallingIdentity(origId);
7603 public void enterPictureInPictureMode(IBinder token) {
7604 final long origId = Binder.clearCallingIdentity();
7606 synchronized(this) {
7607 if (!mSupportsPictureInPicture) {
7608 throw new IllegalStateException("enterPictureInPictureMode: "
7609 + "Device doesn't support picture-in-picture mode.");
7612 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7615 throw new IllegalStateException("enterPictureInPictureMode: "
7616 + "Can't find activity for token=" + token);
7619 if (!r.supportsPictureInPicture()) {
7620 throw new IllegalArgumentException("enterPictureInPictureMode: "
7621 + "Picture-In-Picture not supported for r=" + r);
7624 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7626 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7627 final Rect bounds = (pinnedStack != null)
7628 ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7630 mStackSupervisor.moveActivityToPinnedStackLocked(
7631 r, "enterPictureInPictureMode", bounds);
7634 Binder.restoreCallingIdentity(origId);
7638 // =========================================================
7640 // =========================================================
7642 static class ProcessInfoService extends IProcessInfoService.Stub {
7643 final ActivityManagerService mActivityManagerService;
7644 ProcessInfoService(ActivityManagerService activityManagerService) {
7645 mActivityManagerService = activityManagerService;
7649 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7650 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7651 /*in*/ pids, /*out*/ states, null);
7655 public void getProcessStatesAndOomScoresFromPids(
7656 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7657 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7658 /*in*/ pids, /*out*/ states, /*out*/ scores);
7663 * For each PID in the given input array, write the current process state
7664 * for that process into the states array, or -1 to indicate that no
7665 * process with the given PID exists. If scores array is provided, write
7666 * the oom score for the process into the scores array, with INVALID_ADJ
7667 * indicating the PID doesn't exist.
7669 public void getProcessStatesAndOomScoresForPIDs(
7670 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7671 if (scores != null) {
7672 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7673 "getProcessStatesAndOomScoresForPIDs()");
7677 throw new NullPointerException("pids");
7678 } else if (states == null) {
7679 throw new NullPointerException("states");
7680 } else if (pids.length != states.length) {
7681 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7682 } else if (scores != null && pids.length != scores.length) {
7683 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7686 synchronized (mPidsSelfLocked) {
7687 for (int i = 0; i < pids.length; i++) {
7688 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7689 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7691 if (scores != null) {
7692 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7698 // =========================================================
7700 // =========================================================
7702 static class PermissionController extends IPermissionController.Stub {
7703 ActivityManagerService mActivityManagerService;
7704 PermissionController(ActivityManagerService activityManagerService) {
7705 mActivityManagerService = activityManagerService;
7709 public boolean checkPermission(String permission, int pid, int uid) {
7710 return mActivityManagerService.checkPermission(permission, pid,
7711 uid) == PackageManager.PERMISSION_GRANTED;
7715 public String[] getPackagesForUid(int uid) {
7716 return mActivityManagerService.mContext.getPackageManager()
7717 .getPackagesForUid(uid);
7721 public boolean isRuntimePermission(String permission) {
7723 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7724 .getPermissionInfo(permission, 0);
7725 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7726 } catch (NameNotFoundException nnfe) {
7727 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7733 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7735 public int checkComponentPermission(String permission, int pid, int uid,
7736 int owningUid, boolean exported) {
7737 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7738 owningUid, exported);
7742 public Object getAMSLock() {
7743 return ActivityManagerService.this;
7748 * This can be called with or without the global lock held.
7750 int checkComponentPermission(String permission, int pid, int uid,
7751 int owningUid, boolean exported) {
7752 if (pid == MY_PID) {
7753 return PackageManager.PERMISSION_GRANTED;
7755 return ActivityManager.checkComponentPermission(permission, uid,
7756 owningUid, exported);
7760 * As the only public entry point for permissions checking, this method
7761 * can enforce the semantic that requesting a check on a null global
7762 * permission is automatically denied. (Internally a null permission
7763 * string is used when calling {@link #checkComponentPermission} in cases
7764 * when only uid-based security is needed.)
7766 * This can be called with or without the global lock held.
7769 public int checkPermission(String permission, int pid, int uid) {
7770 if (permission == null) {
7771 return PackageManager.PERMISSION_DENIED;
7773 return checkComponentPermission(permission, pid, uid, -1, true);
7777 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7778 if (permission == null) {
7779 return PackageManager.PERMISSION_DENIED;
7782 // We might be performing an operation on behalf of an indirect binder
7783 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7784 // client identity accordingly before proceeding.
7785 Identity tlsIdentity = sCallerIdentity.get();
7786 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7787 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7788 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7789 uid = tlsIdentity.uid;
7790 pid = tlsIdentity.pid;
7793 return checkComponentPermission(permission, pid, uid, -1, true);
7797 * Binder IPC calls go through the public entry point.
7798 * This can be called with or without the global lock held.
7800 int checkCallingPermission(String permission) {
7801 return checkPermission(permission,
7802 Binder.getCallingPid(),
7803 UserHandle.getAppId(Binder.getCallingUid()));
7807 * This can be called with or without the global lock held.
7809 void enforceCallingPermission(String permission, String func) {
7810 if (checkCallingPermission(permission)
7811 == PackageManager.PERMISSION_GRANTED) {
7815 String msg = "Permission Denial: " + func + " from pid="
7816 + Binder.getCallingPid()
7817 + ", uid=" + Binder.getCallingUid()
7818 + " requires " + permission;
7820 throw new SecurityException(msg);
7824 * Determine if UID is holding permissions required to access {@link Uri} in
7825 * the given {@link ProviderInfo}. Final permission checking is always done
7826 * in {@link ContentProvider}.
7828 private final boolean checkHoldingPermissionsLocked(
7829 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7830 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7831 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7832 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7833 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7834 != PERMISSION_GRANTED) {
7838 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7841 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7842 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7843 if (pi.applicationInfo.uid == uid) {
7845 } else if (!pi.exported) {
7849 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7850 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7852 // check if target holds top-level <provider> permissions
7853 if (!readMet && pi.readPermission != null && considerUidPermissions
7854 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7857 if (!writeMet && pi.writePermission != null && considerUidPermissions
7858 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7862 // track if unprotected read/write is allowed; any denied
7863 // <path-permission> below removes this ability
7864 boolean allowDefaultRead = pi.readPermission == null;
7865 boolean allowDefaultWrite = pi.writePermission == null;
7867 // check if target holds any <path-permission> that match uri
7868 final PathPermission[] pps = pi.pathPermissions;
7870 final String path = grantUri.uri.getPath();
7872 while (i > 0 && (!readMet || !writeMet)) {
7874 PathPermission pp = pps[i];
7875 if (pp.match(path)) {
7877 final String pprperm = pp.getReadPermission();
7878 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7879 "Checking read perm for " + pprperm + " for " + pp.getPath()
7880 + ": match=" + pp.match(path)
7881 + " check=" + pm.checkUidPermission(pprperm, uid));
7882 if (pprperm != null) {
7883 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7884 == PERMISSION_GRANTED) {
7887 allowDefaultRead = false;
7892 final String ppwperm = pp.getWritePermission();
7893 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7894 "Checking write perm " + ppwperm + " for " + pp.getPath()
7895 + ": match=" + pp.match(path)
7896 + " check=" + pm.checkUidPermission(ppwperm, uid));
7897 if (ppwperm != null) {
7898 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7899 == PERMISSION_GRANTED) {
7902 allowDefaultWrite = false;
7910 // grant unprotected <provider> read/write, if not blocked by
7911 // <path-permission> above
7912 if (allowDefaultRead) readMet = true;
7913 if (allowDefaultWrite) writeMet = true;
7915 } catch (RemoteException e) {
7919 return readMet && writeMet;
7922 public int getAppStartMode(int uid, String packageName) {
7923 synchronized (this) {
7924 return checkAllowBackgroundLocked(uid, packageName, -1, true);
7928 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7929 boolean allowWhenForeground) {
7930 UidRecord uidRec = mActiveUids.get(uid);
7931 if (!mLenientBackgroundCheck) {
7932 if (!allowWhenForeground || uidRec == null
7933 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7934 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7935 packageName) != AppOpsManager.MODE_ALLOWED) {
7936 return ActivityManager.APP_START_MODE_DELAYED;
7940 } else if (uidRec == null || uidRec.idle) {
7941 if (callingPid >= 0) {
7943 synchronized (mPidsSelfLocked) {
7944 proc = mPidsSelfLocked.get(callingPid);
7946 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7947 // Whoever is instigating this is in the foreground, so we will allow it
7949 return ActivityManager.APP_START_MODE_NORMAL;
7952 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7953 != AppOpsManager.MODE_ALLOWED) {
7954 return ActivityManager.APP_START_MODE_DELAYED;
7957 return ActivityManager.APP_START_MODE_NORMAL;
7960 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7961 ProviderInfo pi = null;
7962 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7967 pi = AppGlobals.getPackageManager().resolveContentProvider(
7968 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7970 } catch (RemoteException ex) {
7976 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7977 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7978 if (targetUris != null) {
7979 return targetUris.get(grantUri);
7984 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7985 String targetPkg, int targetUid, GrantUri grantUri) {
7986 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7987 if (targetUris == null) {
7988 targetUris = Maps.newArrayMap();
7989 mGrantedUriPermissions.put(targetUid, targetUris);
7992 UriPermission perm = targetUris.get(grantUri);
7994 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7995 targetUris.put(grantUri, perm);
8001 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8002 final int modeFlags) {
8003 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8004 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8005 : UriPermission.STRENGTH_OWNED;
8007 // Root gets to do everything.
8012 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8013 if (perms == null) return false;
8015 // First look for exact match
8016 final UriPermission exactPerm = perms.get(grantUri);
8017 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8021 // No exact match, look for prefixes
8022 final int N = perms.size();
8023 for (int i = 0; i < N; i++) {
8024 final UriPermission perm = perms.valueAt(i);
8025 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8026 && perm.getStrength(modeFlags) >= minStrength) {
8035 * @param uri This uri must NOT contain an embedded userId.
8036 * @param userId The userId in which the uri is to be resolved.
8039 public int checkUriPermission(Uri uri, int pid, int uid,
8040 final int modeFlags, int userId, IBinder callerToken) {
8041 enforceNotIsolatedCaller("checkUriPermission");
8043 // Another redirected-binder-call permissions check as in
8044 // {@link checkPermissionWithToken}.
8045 Identity tlsIdentity = sCallerIdentity.get();
8046 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8047 uid = tlsIdentity.uid;
8048 pid = tlsIdentity.pid;
8051 // Our own process gets to do everything.
8052 if (pid == MY_PID) {
8053 return PackageManager.PERMISSION_GRANTED;
8055 synchronized (this) {
8056 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8057 ? PackageManager.PERMISSION_GRANTED
8058 : PackageManager.PERMISSION_DENIED;
8063 * Check if the targetPkg can be granted permission to access uri by
8064 * the callingUid using the given modeFlags. Throws a security exception
8065 * if callingUid is not allowed to do this. Returns the uid of the target
8066 * if the URI permission grant should be performed; returns -1 if it is not
8067 * needed (for example targetPkg already has permission to access the URI).
8068 * If you already know the uid of the target, you can supply it in
8069 * lastTargetUid else set that to -1.
8071 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8072 final int modeFlags, int lastTargetUid) {
8073 if (!Intent.isAccessUriMode(modeFlags)) {
8077 if (targetPkg != null) {
8078 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079 "Checking grant " + targetPkg + " permission to " + grantUri);
8082 final IPackageManager pm = AppGlobals.getPackageManager();
8084 // If this is not a content: uri, we can't do anything with it.
8085 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8086 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8087 "Can't grant URI permission for non-content URI: " + grantUri);
8091 final String authority = grantUri.uri.getAuthority();
8092 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8093 MATCH_DEBUG_TRIAGED_MISSING);
8095 Slog.w(TAG, "No content provider found for permission check: " +
8096 grantUri.uri.toSafeString());
8100 int targetUid = lastTargetUid;
8101 if (targetUid < 0 && targetPkg != null) {
8103 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8104 UserHandle.getUserId(callingUid));
8105 if (targetUid < 0) {
8106 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8107 "Can't grant URI permission no uid for: " + targetPkg);
8110 } catch (RemoteException ex) {
8115 if (targetUid >= 0) {
8116 // First... does the target actually need this permission?
8117 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8118 // No need to grant the target this permission.
8119 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8120 "Target " + targetPkg + " already has full permission to " + grantUri);
8124 // First... there is no target package, so can anyone access it?
8125 boolean allowed = pi.exported;
8126 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8127 if (pi.readPermission != null) {
8131 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8132 if (pi.writePermission != null) {
8141 /* There is a special cross user grant if:
8142 * - The target is on another user.
8143 * - Apps on the current user can access the uri without any uid permissions.
8144 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8145 * grant uri permissions.
8147 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8148 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8149 modeFlags, false /*without considering the uid permissions*/);
8151 // Second... is the provider allowing granting of URI permissions?
8152 if (!specialCrossUserGrant) {
8153 if (!pi.grantUriPermissions) {
8154 throw new SecurityException("Provider " + pi.packageName
8156 + " does not allow granting of Uri permissions (uri "
8159 if (pi.uriPermissionPatterns != null) {
8160 final int N = pi.uriPermissionPatterns.length;
8161 boolean allowed = false;
8162 for (int i=0; i<N; i++) {
8163 if (pi.uriPermissionPatterns[i] != null
8164 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8170 throw new SecurityException("Provider " + pi.packageName
8172 + " does not allow granting of permission to path of Uri "
8178 // Third... does the caller itself have permission to access
8180 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8181 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8182 // Require they hold a strong enough Uri permission
8183 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8184 throw new SecurityException("Uid " + callingUid
8185 + " does not have permission to uri " + grantUri);
8193 * @param uri This uri must NOT contain an embedded userId.
8194 * @param userId The userId in which the uri is to be resolved.
8197 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8198 final int modeFlags, int userId) {
8199 enforceNotIsolatedCaller("checkGrantUriPermission");
8200 synchronized(this) {
8201 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8202 new GrantUri(userId, uri, false), modeFlags, -1);
8206 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8207 final int modeFlags, UriPermissionOwner owner) {
8208 if (!Intent.isAccessUriMode(modeFlags)) {
8212 // So here we are: the caller has the assumed permission
8213 // to the uri, and the target doesn't. Let's now give this to
8216 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8217 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8219 final String authority = grantUri.uri.getAuthority();
8220 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8221 MATCH_DEBUG_TRIAGED_MISSING);
8223 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8227 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8228 grantUri.prefix = true;
8230 final UriPermission perm = findOrCreateUriPermissionLocked(
8231 pi.packageName, targetPkg, targetUid, grantUri);
8232 perm.grantModes(modeFlags, owner);
8235 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8236 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8237 if (targetPkg == null) {
8238 throw new NullPointerException("targetPkg");
8241 final IPackageManager pm = AppGlobals.getPackageManager();
8243 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8244 } catch (RemoteException ex) {
8248 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8250 if (targetUid < 0) {
8254 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8258 static class NeededUriGrants extends ArrayList<GrantUri> {
8259 final String targetPkg;
8260 final int targetUid;
8263 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8264 this.targetPkg = targetPkg;
8265 this.targetUid = targetUid;
8271 * Like checkGrantUriPermissionLocked, but takes an Intent.
8273 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8274 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8275 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8276 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8277 + " clip=" + (intent != null ? intent.getClipData() : null)
8278 + " from " + intent + "; flags=0x"
8279 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8281 if (targetPkg == null) {
8282 throw new NullPointerException("targetPkg");
8285 if (intent == null) {
8288 Uri data = intent.getData();
8289 ClipData clip = intent.getClipData();
8290 if (data == null && clip == null) {
8293 // Default userId for uris in the intent (if they don't specify it themselves)
8294 int contentUserHint = intent.getContentUserHint();
8295 if (contentUserHint == UserHandle.USER_CURRENT) {
8296 contentUserHint = UserHandle.getUserId(callingUid);
8298 final IPackageManager pm = AppGlobals.getPackageManager();
8300 if (needed != null) {
8301 targetUid = needed.targetUid;
8304 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8306 } catch (RemoteException ex) {
8309 if (targetUid < 0) {
8310 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8311 "Can't grant URI permission no uid for: " + targetPkg
8312 + " on user " + targetUserId);
8317 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8318 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8320 if (targetUid > 0) {
8321 if (needed == null) {
8322 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8324 needed.add(grantUri);
8328 for (int i=0; i<clip.getItemCount(); i++) {
8329 Uri uri = clip.getItemAt(i).getUri();
8331 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8332 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8334 if (targetUid > 0) {
8335 if (needed == null) {
8336 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8338 needed.add(grantUri);
8341 Intent clipIntent = clip.getItemAt(i).getIntent();
8342 if (clipIntent != null) {
8343 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8344 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8345 if (newNeeded != null) {
8357 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8359 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8360 UriPermissionOwner owner) {
8361 if (needed != null) {
8362 for (int i=0; i<needed.size(); i++) {
8363 GrantUri grantUri = needed.get(i);
8364 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8365 grantUri, needed.flags, owner);
8370 void grantUriPermissionFromIntentLocked(int callingUid,
8371 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8372 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8373 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8374 if (needed == null) {
8378 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8382 * @param uri This uri must NOT contain an embedded userId.
8383 * @param userId The userId in which the uri is to be resolved.
8386 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8387 final int modeFlags, int userId) {
8388 enforceNotIsolatedCaller("grantUriPermission");
8389 GrantUri grantUri = new GrantUri(userId, uri, false);
8390 synchronized(this) {
8391 final ProcessRecord r = getRecordForAppLocked(caller);
8393 throw new SecurityException("Unable to find app for caller "
8395 + " when granting permission to uri " + grantUri);
8397 if (targetPkg == null) {
8398 throw new IllegalArgumentException("null target");
8400 if (grantUri == null) {
8401 throw new IllegalArgumentException("null uri");
8404 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8405 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8406 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8407 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8409 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8410 UserHandle.getUserId(r.uid));
8414 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8415 if (perm.modeFlags == 0) {
8416 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8418 if (perms != null) {
8419 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8420 "Removing " + perm.targetUid + " permission to " + perm.uri);
8422 perms.remove(perm.uri);
8423 if (perms.isEmpty()) {
8424 mGrantedUriPermissions.remove(perm.targetUid);
8430 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8431 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8432 "Revoking all granted permissions to " + grantUri);
8434 final IPackageManager pm = AppGlobals.getPackageManager();
8435 final String authority = grantUri.uri.getAuthority();
8436 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8437 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8439 Slog.w(TAG, "No content provider found for permission revoke: "
8440 + grantUri.toSafeString());
8444 // Does the caller have this permission on the URI?
8445 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8446 // If they don't have direct access to the URI, then revoke any
8447 // ownerless URI permissions that have been granted to them.
8448 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8449 if (perms != null) {
8450 boolean persistChanged = false;
8451 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8452 final UriPermission perm = it.next();
8453 if (perm.uri.sourceUserId == grantUri.sourceUserId
8454 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8455 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8456 "Revoking non-owned " + perm.targetUid
8457 + " permission to " + perm.uri);
8458 persistChanged |= perm.revokeModes(
8459 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8460 if (perm.modeFlags == 0) {
8465 if (perms.isEmpty()) {
8466 mGrantedUriPermissions.remove(callingUid);
8468 if (persistChanged) {
8469 schedulePersistUriGrants();
8475 boolean persistChanged = false;
8477 // Go through all of the permissions and remove any that match.
8478 int N = mGrantedUriPermissions.size();
8479 for (int i = 0; i < N; i++) {
8480 final int targetUid = mGrantedUriPermissions.keyAt(i);
8481 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8483 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8484 final UriPermission perm = it.next();
8485 if (perm.uri.sourceUserId == grantUri.sourceUserId
8486 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8487 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8488 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8489 persistChanged |= perm.revokeModes(
8490 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8491 if (perm.modeFlags == 0) {
8497 if (perms.isEmpty()) {
8498 mGrantedUriPermissions.remove(targetUid);
8504 if (persistChanged) {
8505 schedulePersistUriGrants();
8510 * @param uri This uri must NOT contain an embedded userId.
8511 * @param userId The userId in which the uri is to be resolved.
8514 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8516 enforceNotIsolatedCaller("revokeUriPermission");
8517 synchronized(this) {
8518 final ProcessRecord r = getRecordForAppLocked(caller);
8520 throw new SecurityException("Unable to find app for caller "
8522 + " when revoking permission to uri " + uri);
8525 Slog.w(TAG, "revokeUriPermission: null uri");
8529 if (!Intent.isAccessUriMode(modeFlags)) {
8533 final String authority = uri.getAuthority();
8534 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8535 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8537 Slog.w(TAG, "No content provider found for permission revoke: "
8538 + uri.toSafeString());
8542 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8547 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8550 * @param packageName Package name to match, or {@code null} to apply to all
8552 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8554 * @param persistable If persistable grants should be removed.
8556 private void removeUriPermissionsForPackageLocked(
8557 String packageName, int userHandle, boolean persistable) {
8558 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8559 throw new IllegalArgumentException("Must narrow by either package or user");
8562 boolean persistChanged = false;
8564 int N = mGrantedUriPermissions.size();
8565 for (int i = 0; i < N; i++) {
8566 final int targetUid = mGrantedUriPermissions.keyAt(i);
8567 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8569 // Only inspect grants matching user
8570 if (userHandle == UserHandle.USER_ALL
8571 || userHandle == UserHandle.getUserId(targetUid)) {
8572 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8573 final UriPermission perm = it.next();
8575 // Only inspect grants matching package
8576 if (packageName == null || perm.sourcePkg.equals(packageName)
8577 || perm.targetPkg.equals(packageName)) {
8578 // Hacky solution as part of fixing a security bug; ignore
8579 // grants associated with DownloadManager so we don't have
8580 // to immediately launch it to regrant the permissions
8581 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8582 && !persistable) continue;
8584 persistChanged |= perm.revokeModes(persistable
8585 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8587 // Only remove when no modes remain; any persisted grants
8588 // will keep this alive.
8589 if (perm.modeFlags == 0) {
8595 if (perms.isEmpty()) {
8596 mGrantedUriPermissions.remove(targetUid);
8603 if (persistChanged) {
8604 schedulePersistUriGrants();
8609 public IBinder newUriPermissionOwner(String name) {
8610 enforceNotIsolatedCaller("newUriPermissionOwner");
8611 synchronized(this) {
8612 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8613 return owner.getExternalTokenLocked();
8618 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8619 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8620 synchronized(this) {
8621 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8623 throw new IllegalArgumentException("Activity does not exist; token="
8626 return r.getUriPermissionsLocked().getExternalTokenLocked();
8630 * @param uri This uri must NOT contain an embedded userId.
8631 * @param sourceUserId The userId in which the uri is to be resolved.
8632 * @param targetUserId The userId of the app that receives the grant.
8635 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8636 final int modeFlags, int sourceUserId, int targetUserId) {
8637 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8638 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8639 "grantUriPermissionFromOwner", null);
8640 synchronized(this) {
8641 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8642 if (owner == null) {
8643 throw new IllegalArgumentException("Unknown owner: " + token);
8645 if (fromUid != Binder.getCallingUid()) {
8646 if (Binder.getCallingUid() != Process.myUid()) {
8647 // Only system code can grant URI permissions on behalf
8649 throw new SecurityException("nice try");
8652 if (targetPkg == null) {
8653 throw new IllegalArgumentException("null target");
8656 throw new IllegalArgumentException("null uri");
8659 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8660 modeFlags, owner, targetUserId);
8665 * @param uri This uri must NOT contain an embedded userId.
8666 * @param userId The userId in which the uri is to be resolved.
8669 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8670 synchronized(this) {
8671 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8672 if (owner == null) {
8673 throw new IllegalArgumentException("Unknown owner: " + token);
8677 owner.removeUriPermissionsLocked(mode);
8679 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8680 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8685 private void schedulePersistUriGrants() {
8686 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8687 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8688 10 * DateUtils.SECOND_IN_MILLIS);
8692 private void writeGrantedUriPermissions() {
8693 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8695 // Snapshot permissions so we can persist without lock
8696 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8697 synchronized (this) {
8698 final int size = mGrantedUriPermissions.size();
8699 for (int i = 0; i < size; i++) {
8700 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8701 for (UriPermission perm : perms.values()) {
8702 if (perm.persistedModeFlags != 0) {
8703 persist.add(perm.snapshot());
8709 FileOutputStream fos = null;
8711 fos = mGrantFile.startWrite();
8713 XmlSerializer out = new FastXmlSerializer();
8714 out.setOutput(fos, StandardCharsets.UTF_8.name());
8715 out.startDocument(null, true);
8716 out.startTag(null, TAG_URI_GRANTS);
8717 for (UriPermission.Snapshot perm : persist) {
8718 out.startTag(null, TAG_URI_GRANT);
8719 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8720 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8721 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8722 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8723 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8724 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8725 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8726 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8727 out.endTag(null, TAG_URI_GRANT);
8729 out.endTag(null, TAG_URI_GRANTS);
8732 mGrantFile.finishWrite(fos);
8733 } catch (IOException e) {
8735 mGrantFile.failWrite(fos);
8740 private void readGrantedUriPermissionsLocked() {
8741 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8743 final long now = System.currentTimeMillis();
8745 FileInputStream fis = null;
8747 fis = mGrantFile.openRead();
8748 final XmlPullParser in = Xml.newPullParser();
8749 in.setInput(fis, StandardCharsets.UTF_8.name());
8752 while ((type = in.next()) != END_DOCUMENT) {
8753 final String tag = in.getName();
8754 if (type == START_TAG) {
8755 if (TAG_URI_GRANT.equals(tag)) {
8756 final int sourceUserId;
8757 final int targetUserId;
8758 final int userHandle = readIntAttribute(in,
8759 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8760 if (userHandle != UserHandle.USER_NULL) {
8761 // For backwards compatibility.
8762 sourceUserId = userHandle;
8763 targetUserId = userHandle;
8765 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8766 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8768 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8769 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8770 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8771 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8772 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8773 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8775 // Sanity check that provider still belongs to source package
8776 // Both direct boot aware and unaware packages are fine as we
8777 // will do filtering at query time to avoid multiple parsing.
8778 final ProviderInfo pi = getProviderInfoLocked(
8779 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8780 | MATCH_DIRECT_BOOT_UNAWARE);
8781 if (pi != null && sourcePkg.equals(pi.packageName)) {
8784 targetUid = AppGlobals.getPackageManager().getPackageUid(
8785 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8786 } catch (RemoteException e) {
8788 if (targetUid != -1) {
8789 final UriPermission perm = findOrCreateUriPermissionLocked(
8790 sourcePkg, targetPkg, targetUid,
8791 new GrantUri(sourceUserId, uri, prefix));
8792 perm.initPersistedModes(modeFlags, createdTime);
8795 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8796 + " but instead found " + pi);
8801 } catch (FileNotFoundException e) {
8802 // Missing grants is okay
8803 } catch (IOException e) {
8804 Slog.wtf(TAG, "Failed reading Uri grants", e);
8805 } catch (XmlPullParserException e) {
8806 Slog.wtf(TAG, "Failed reading Uri grants", e);
8808 IoUtils.closeQuietly(fis);
8813 * @param uri This uri must NOT contain an embedded userId.
8814 * @param userId The userId in which the uri is to be resolved.
8817 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8818 enforceNotIsolatedCaller("takePersistableUriPermission");
8820 Preconditions.checkFlagsArgument(modeFlags,
8821 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8823 synchronized (this) {
8824 final int callingUid = Binder.getCallingUid();
8825 boolean persistChanged = false;
8826 GrantUri grantUri = new GrantUri(userId, uri, false);
8828 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8829 new GrantUri(userId, uri, false));
8830 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8831 new GrantUri(userId, uri, true));
8833 final boolean exactValid = (exactPerm != null)
8834 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8835 final boolean prefixValid = (prefixPerm != null)
8836 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8838 if (!(exactValid || prefixValid)) {
8839 throw new SecurityException("No persistable permission grants found for UID "
8840 + callingUid + " and Uri " + grantUri.toSafeString());
8844 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8847 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8850 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8852 if (persistChanged) {
8853 schedulePersistUriGrants();
8859 * @param uri This uri must NOT contain an embedded userId.
8860 * @param userId The userId in which the uri is to be resolved.
8863 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8864 enforceNotIsolatedCaller("releasePersistableUriPermission");
8866 Preconditions.checkFlagsArgument(modeFlags,
8867 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8869 synchronized (this) {
8870 final int callingUid = Binder.getCallingUid();
8871 boolean persistChanged = false;
8873 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8874 new GrantUri(userId, uri, false));
8875 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8876 new GrantUri(userId, uri, true));
8877 if (exactPerm == null && prefixPerm == null) {
8878 throw new SecurityException("No permission grants found for UID " + callingUid
8879 + " and Uri " + uri.toSafeString());
8882 if (exactPerm != null) {
8883 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8884 removeUriPermissionIfNeededLocked(exactPerm);
8886 if (prefixPerm != null) {
8887 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8888 removeUriPermissionIfNeededLocked(prefixPerm);
8891 if (persistChanged) {
8892 schedulePersistUriGrants();
8898 * Prune any older {@link UriPermission} for the given UID until outstanding
8899 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8901 * @return if any mutations occured that require persisting.
8903 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8904 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8905 if (perms == null) return false;
8906 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8908 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8909 for (UriPermission perm : perms.values()) {
8910 if (perm.persistedModeFlags != 0) {
8911 persisted.add(perm);
8915 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8916 if (trimCount <= 0) return false;
8918 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8919 for (int i = 0; i < trimCount; i++) {
8920 final UriPermission perm = persisted.get(i);
8922 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8923 "Trimming grant created at " + perm.persistedCreateTime);
8925 perm.releasePersistableModes(~0);
8926 removeUriPermissionIfNeededLocked(perm);
8933 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8934 String packageName, boolean incoming) {
8935 enforceNotIsolatedCaller("getPersistedUriPermissions");
8936 Preconditions.checkNotNull(packageName, "packageName");
8938 final int callingUid = Binder.getCallingUid();
8939 final int callingUserId = UserHandle.getUserId(callingUid);
8940 final IPackageManager pm = AppGlobals.getPackageManager();
8942 final int packageUid = pm.getPackageUid(packageName,
8943 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8944 if (packageUid != callingUid) {
8945 throw new SecurityException(
8946 "Package " + packageName + " does not belong to calling UID " + callingUid);
8948 } catch (RemoteException e) {
8949 throw new SecurityException("Failed to verify package name ownership");
8952 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8953 synchronized (this) {
8955 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8957 if (perms == null) {
8958 Slog.w(TAG, "No permission grants found for " + packageName);
8960 for (UriPermission perm : perms.values()) {
8961 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8962 result.add(perm.buildPersistedPublicApiObject());
8967 final int size = mGrantedUriPermissions.size();
8968 for (int i = 0; i < size; i++) {
8969 final ArrayMap<GrantUri, UriPermission> perms =
8970 mGrantedUriPermissions.valueAt(i);
8971 for (UriPermission perm : perms.values()) {
8972 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8973 result.add(perm.buildPersistedPublicApiObject());
8979 return new ParceledListSlice<android.content.UriPermission>(result);
8983 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8984 String packageName, int userId) {
8985 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8986 "getGrantedUriPermissions");
8988 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8989 synchronized (this) {
8990 final int size = mGrantedUriPermissions.size();
8991 for (int i = 0; i < size; i++) {
8992 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8993 for (UriPermission perm : perms.values()) {
8994 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8995 && perm.persistedModeFlags != 0) {
8996 result.add(perm.buildPersistedPublicApiObject());
9001 return new ParceledListSlice<android.content.UriPermission>(result);
9005 public void clearGrantedUriPermissions(String packageName, int userId) {
9006 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9007 "clearGrantedUriPermissions");
9008 removeUriPermissionsForPackageLocked(packageName, userId, true);
9012 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9013 synchronized (this) {
9015 who != null ? getRecordForAppLocked(who) : null;
9016 if (app == null) return;
9018 Message msg = Message.obtain();
9019 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9021 msg.arg1 = waiting ? 1 : 0;
9022 mUiHandler.sendMessage(msg);
9027 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9028 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9029 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9030 outInfo.availMem = Process.getFreeMemory();
9031 outInfo.totalMem = Process.getTotalMemory();
9032 outInfo.threshold = homeAppMem;
9033 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9034 outInfo.hiddenAppThreshold = cachedAppMem;
9035 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9036 ProcessList.SERVICE_ADJ);
9037 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9038 ProcessList.VISIBLE_APP_ADJ);
9039 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9040 ProcessList.FOREGROUND_APP_ADJ);
9043 // =========================================================
9045 // =========================================================
9048 public List<IAppTask> getAppTasks(String callingPackage) {
9049 int callingUid = Binder.getCallingUid();
9050 long ident = Binder.clearCallingIdentity();
9052 synchronized(this) {
9053 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9055 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9057 final int N = mRecentTasks.size();
9058 for (int i = 0; i < N; i++) {
9059 TaskRecord tr = mRecentTasks.get(i);
9060 // Skip tasks that do not match the caller. We don't need to verify
9061 // callingPackage, because we are also limiting to callingUid and know
9062 // that will limit to the correct security sandbox.
9063 if (tr.effectiveUid != callingUid) {
9066 Intent intent = tr.getBaseIntent();
9067 if (intent == null ||
9068 !callingPackage.equals(intent.getComponent().getPackageName())) {
9071 ActivityManager.RecentTaskInfo taskInfo =
9072 createRecentTaskInfoFromTaskRecord(tr);
9073 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9077 Binder.restoreCallingIdentity(ident);
9084 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9085 final int callingUid = Binder.getCallingUid();
9086 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9088 synchronized(this) {
9089 if (DEBUG_ALL) Slog.v(
9090 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9092 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9095 // TODO: Improve with MRU list from all ActivityStacks.
9096 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9103 * Creates a new RecentTaskInfo from a TaskRecord.
9105 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9106 // Update the task description to reflect any changes in the task stack
9107 tr.updateTaskDescription();
9109 // Compose the recent task info
9110 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9111 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9112 rti.persistentId = tr.taskId;
9113 rti.baseIntent = new Intent(tr.getBaseIntent());
9114 rti.origActivity = tr.origActivity;
9115 rti.realActivity = tr.realActivity;
9116 rti.description = tr.lastDescription;
9117 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9118 rti.userId = tr.userId;
9119 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9120 rti.firstActiveTime = tr.firstActiveTime;
9121 rti.lastActiveTime = tr.lastActiveTime;
9122 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9123 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9124 rti.numActivities = 0;
9125 if (tr.mBounds != null) {
9126 rti.bounds = new Rect(tr.mBounds);
9128 rti.isDockable = tr.canGoInDockedStack();
9129 rti.resizeMode = tr.mResizeMode;
9131 ActivityRecord base = null;
9132 ActivityRecord top = null;
9135 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9136 tmp = tr.mActivities.get(i);
9137 if (tmp.finishing) {
9141 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9144 rti.numActivities++;
9147 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9148 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9153 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9154 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9155 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9157 if (checkPermission(android.Manifest.permission.GET_TASKS,
9158 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9159 // Temporary compatibility: some existing apps on the system image may
9160 // still be requesting the old permission and not switched to the new
9161 // one; if so, we'll still allow them full access. This means we need
9162 // to see if they are holding the old permission and are a system app.
9164 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9166 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9167 + " is using old GET_TASKS but privileged; allowing");
9169 } catch (RemoteException e) {
9174 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9175 + " does not hold REAL_GET_TASKS; limiting output");
9181 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9183 final int callingUid = Binder.getCallingUid();
9184 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9185 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9187 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9188 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9189 synchronized (this) {
9190 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9192 final boolean detailed = checkCallingPermission(
9193 android.Manifest.permission.GET_DETAILED_TASKS)
9194 == PackageManager.PERMISSION_GRANTED;
9196 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9197 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9198 return ParceledListSlice.emptyList();
9200 mRecentTasks.loadUserRecentsLocked(userId);
9202 final int recentsCount = mRecentTasks.size();
9203 ArrayList<ActivityManager.RecentTaskInfo> res =
9204 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9206 final Set<Integer> includedUsers;
9207 if (includeProfiles) {
9208 includedUsers = mUserController.getProfileIds(userId);
9210 includedUsers = new HashSet<>();
9212 includedUsers.add(Integer.valueOf(userId));
9214 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9215 TaskRecord tr = mRecentTasks.get(i);
9216 // Only add calling user or related users recent tasks
9217 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9218 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9222 if (tr.realActivitySuspended) {
9223 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9227 // Return the entry if desired by the caller. We always return
9228 // the first entry, because callers always expect this to be the
9229 // foreground app. We may filter others if the caller has
9230 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9231 // we should exclude the entry.
9235 || (tr.intent == null)
9236 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9239 // If the caller doesn't have the GET_TASKS permission, then only
9240 // allow them to see a small subset of tasks -- their own and home.
9241 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9242 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9246 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9247 if (tr.stack != null && tr.stack.isHomeStack()) {
9248 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9249 "Skipping, home stack task: " + tr);
9253 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9254 final ActivityStack stack = tr.stack;
9255 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9256 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9257 "Skipping, top task in docked stack: " + tr);
9261 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9262 if (tr.stack != null && tr.stack.isPinnedStack()) {
9263 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9264 "Skipping, pinned stack task: " + tr);
9268 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9269 // Don't include auto remove tasks that are finished or finishing.
9270 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9271 "Skipping, auto-remove without activity: " + tr);
9274 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9275 && !tr.isAvailable) {
9276 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9277 "Skipping, unavail real act: " + tr);
9281 if (!tr.mUserSetupComplete) {
9282 // Don't include task launched while user is not done setting-up.
9283 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9284 "Skipping, user setup not complete: " + tr);
9288 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9290 rti.baseIntent.replaceExtras((Bundle)null);
9297 return new ParceledListSlice<>(res);
9302 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9303 synchronized (this) {
9304 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9305 "getTaskThumbnail()");
9306 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9307 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9309 return tr.getTaskThumbnailLocked();
9316 public int addAppTask(IBinder activityToken, Intent intent,
9317 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9318 final int callingUid = Binder.getCallingUid();
9319 final long callingIdent = Binder.clearCallingIdentity();
9322 synchronized (this) {
9323 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9325 throw new IllegalArgumentException("Activity does not exist; token="
9328 ComponentName comp = intent.getComponent();
9330 throw new IllegalArgumentException("Intent " + intent
9331 + " must specify explicit component");
9333 if (thumbnail.getWidth() != mThumbnailWidth
9334 || thumbnail.getHeight() != mThumbnailHeight) {
9335 throw new IllegalArgumentException("Bad thumbnail size: got "
9336 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9337 + mThumbnailWidth + "x" + mThumbnailHeight);
9339 if (intent.getSelector() != null) {
9340 intent.setSelector(null);
9342 if (intent.getSourceBounds() != null) {
9343 intent.setSourceBounds(null);
9345 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9346 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9347 // The caller has added this as an auto-remove task... that makes no
9348 // sense, so turn off auto-remove.
9349 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9352 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9353 mLastAddedTaskActivity = null;
9355 ActivityInfo ainfo = mLastAddedTaskActivity;
9356 if (ainfo == null) {
9357 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9358 comp, 0, UserHandle.getUserId(callingUid));
9359 if (ainfo.applicationInfo.uid != callingUid) {
9360 throw new SecurityException(
9361 "Can't add task for another application: target uid="
9362 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9366 // Use the full screen as the context for the task thumbnail
9367 final Point displaySize = new Point();
9368 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9369 r.task.stack.getDisplaySize(displaySize);
9370 thumbnailInfo.taskWidth = displaySize.x;
9371 thumbnailInfo.taskHeight = displaySize.y;
9372 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9374 TaskRecord task = new TaskRecord(this,
9375 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9376 ainfo, intent, description, thumbnailInfo);
9378 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9380 // If this would have caused a trim, then we'll abort because that
9381 // means it would be added at the end of the list but then just removed.
9382 return INVALID_TASK_ID;
9385 final int N = mRecentTasks.size();
9386 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9387 final TaskRecord tr = mRecentTasks.remove(N - 1);
9388 tr.removedFromRecents();
9391 task.inRecents = true;
9392 mRecentTasks.add(task);
9393 r.task.stack.addTask(task, false, "addAppTask");
9395 task.setLastThumbnailLocked(thumbnail);
9396 task.freeLastThumbnail();
9401 Binder.restoreCallingIdentity(callingIdent);
9406 public Point getAppTaskThumbnailSize() {
9407 synchronized (this) {
9408 return new Point(mThumbnailWidth, mThumbnailHeight);
9413 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9414 synchronized (this) {
9415 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9417 r.setTaskDescription(td);
9418 r.task.updateTaskDescription();
9424 public void setTaskResizeable(int taskId, int resizeableMode) {
9425 synchronized (this) {
9426 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9427 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9429 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9432 if (task.mResizeMode != resizeableMode) {
9433 task.mResizeMode = resizeableMode;
9434 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9435 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9436 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9442 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9443 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9444 long ident = Binder.clearCallingIdentity();
9446 synchronized (this) {
9447 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9449 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9452 int stackId = task.stack.mStackId;
9453 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9454 // in crop windows resize mode or if the task size is affected by the docked stack
9455 // changing size. No need to update configuration.
9456 if (bounds != null && task.inCropWindowsResizeMode()
9457 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9458 mWindowManager.scrollTask(task.taskId, bounds);
9462 // Place the task in the right stack if it isn't there already based on
9463 // the requested bounds.
9464 // The stack transition logic is:
9465 // - a null bounds on a freeform task moves that task to fullscreen
9466 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9467 // that task to freeform
9468 // - otherwise the task is not moved
9469 if (!StackId.isTaskResizeAllowed(stackId)) {
9470 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9472 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9473 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9474 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9475 stackId = FREEFORM_WORKSPACE_STACK_ID;
9477 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9478 if (stackId != task.stack.mStackId) {
9479 mStackSupervisor.moveTaskToStackUncheckedLocked(
9480 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9481 preserveWindow = false;
9484 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9485 false /* deferResume */);
9488 Binder.restoreCallingIdentity(ident);
9493 public Rect getTaskBounds(int taskId) {
9494 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9495 long ident = Binder.clearCallingIdentity();
9496 Rect rect = new Rect();
9498 synchronized (this) {
9499 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9500 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9502 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9505 if (task.stack != null) {
9506 // Return the bounds from window manager since it will be adjusted for various
9507 // things like the presense of a docked stack for tasks that aren't resizeable.
9508 mWindowManager.getTaskBounds(task.taskId, rect);
9510 // Task isn't in window manager yet since it isn't associated with a stack.
9511 // Return the persist value from activity manager
9512 if (task.mBounds != null) {
9513 rect.set(task.mBounds);
9514 } else if (task.mLastNonFullscreenBounds != null) {
9515 rect.set(task.mLastNonFullscreenBounds);
9520 Binder.restoreCallingIdentity(ident);
9526 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9527 if (userId != UserHandle.getCallingUserId()) {
9528 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9529 "getTaskDescriptionIcon");
9531 final File passedIconFile = new File(filePath);
9532 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9533 passedIconFile.getName());
9534 if (!legitIconFile.getPath().equals(filePath)
9535 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9536 throw new IllegalArgumentException("Bad file path: " + filePath
9537 + " passed for userId " + userId);
9539 return mRecentTasks.getTaskDescriptionIcon(filePath);
9543 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9544 throws RemoteException {
9545 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9546 opts.getCustomInPlaceResId() == 0) {
9547 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9548 "with valid animation");
9550 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9551 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9552 opts.getCustomInPlaceResId());
9553 mWindowManager.executeAppTransition();
9556 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9557 boolean removeFromRecents) {
9558 if (removeFromRecents) {
9559 mRecentTasks.remove(tr);
9560 tr.removedFromRecents();
9562 ComponentName component = tr.getBaseIntent().getComponent();
9563 if (component == null) {
9564 Slog.w(TAG, "No component for base intent of task: " + tr);
9568 // Find any running services associated with this app and stop if needed.
9569 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9575 // Determine if the process(es) for this task should be killed.
9576 final String pkg = component.getPackageName();
9577 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9578 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9579 for (int i = 0; i < pmap.size(); i++) {
9581 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9582 for (int j = 0; j < uids.size(); j++) {
9583 ProcessRecord proc = uids.valueAt(j);
9584 if (proc.userId != tr.userId) {
9585 // Don't kill process for a different user.
9588 if (proc == mHomeProcess) {
9589 // Don't kill the home process along with tasks from the same package.
9592 if (!proc.pkgList.containsKey(pkg)) {
9593 // Don't kill process that is not associated with this task.
9597 for (int k = 0; k < proc.activities.size(); k++) {
9598 TaskRecord otherTask = proc.activities.get(k).task;
9599 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9600 // Don't kill process(es) that has an activity in a different task that is
9606 if (proc.foregroundServices) {
9607 // Don't kill process(es) with foreground service.
9611 // Add process to kill list.
9612 procsToKill.add(proc);
9616 // Kill the running processes.
9617 for (int i = 0; i < procsToKill.size(); i++) {
9618 ProcessRecord pr = procsToKill.get(i);
9619 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9620 && pr.curReceiver == null) {
9621 pr.kill("remove task", true);
9623 // We delay killing processes that are not in the background or running a receiver.
9624 pr.waitingToKill = "remove task";
9629 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9630 // Remove all tasks with activities in the specified package from the list of recent tasks
9631 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9632 TaskRecord tr = mRecentTasks.get(i);
9633 if (tr.userId != userId) continue;
9635 ComponentName cn = tr.intent.getComponent();
9636 if (cn != null && cn.getPackageName().equals(packageName)) {
9637 // If the package name matches, remove the task.
9638 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9643 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9646 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9647 TaskRecord tr = mRecentTasks.get(i);
9648 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9652 ComponentName cn = tr.intent.getComponent();
9653 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9654 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9655 if (sameComponent) {
9656 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9662 * Removes the task with the specified task id.
9664 * @param taskId Identifier of the task to be removed.
9665 * @param killProcess Kill any process associated with the task if possible.
9666 * @param removeFromRecents Whether to also remove the task from recents.
9667 * @return Returns true if the given task was found and removed.
9669 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9670 boolean removeFromRecents) {
9671 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9672 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9674 tr.removeTaskActivitiesLocked();
9675 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9676 if (tr.isPersistable) {
9677 notifyTaskPersisterLocked(null, true);
9681 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9686 public void removeStack(int stackId) {
9687 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9688 if (stackId == HOME_STACK_ID) {
9689 throw new IllegalArgumentException("Removing home stack is not allowed.");
9692 synchronized (this) {
9693 final long ident = Binder.clearCallingIdentity();
9695 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9696 if (stack == null) {
9699 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9700 for (int i = tasks.size() - 1; i >= 0; i--) {
9701 removeTaskByIdLocked(
9702 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9705 Binder.restoreCallingIdentity(ident);
9711 public boolean removeTask(int taskId) {
9712 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9713 synchronized (this) {
9714 final long ident = Binder.clearCallingIdentity();
9716 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9718 Binder.restoreCallingIdentity(ident);
9724 * TODO: Add mController hook
9727 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9728 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9730 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9731 synchronized(this) {
9732 moveTaskToFrontLocked(taskId, flags, bOptions);
9736 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9737 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9739 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9740 Binder.getCallingUid(), -1, -1, "Task to front")) {
9741 ActivityOptions.abort(options);
9744 final long origId = Binder.clearCallingIdentity();
9746 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9748 Slog.d(TAG, "Could not find task for id: "+ taskId);
9751 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9752 mStackSupervisor.showLockTaskToast();
9753 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9756 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9757 if (prev != null && prev.isRecentsActivity()) {
9758 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9760 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9761 false /* forceNonResizable */);
9763 Binder.restoreCallingIdentity(origId);
9765 ActivityOptions.abort(options);
9769 * Moves an activity, and all of the other activities within the same task, to the bottom
9770 * of the history stack. The activity's order within the task is unchanged.
9772 * @param token A reference to the activity we wish to move
9773 * @param nonRoot If false then this only works if the activity is the root
9774 * of a task; if true it will work for any activity in a task.
9775 * @return Returns true if the move completed, false if not.
9778 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9779 enforceNotIsolatedCaller("moveActivityTaskToBack");
9780 synchronized(this) {
9781 final long origId = Binder.clearCallingIdentity();
9783 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9784 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9786 if (mStackSupervisor.isLockedTask(task)) {
9787 mStackSupervisor.showLockTaskToast();
9790 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9793 Binder.restoreCallingIdentity(origId);
9800 public void moveTaskBackwards(int task) {
9801 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9802 "moveTaskBackwards()");
9804 synchronized(this) {
9805 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9806 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9809 final long origId = Binder.clearCallingIdentity();
9810 moveTaskBackwardsLocked(task);
9811 Binder.restoreCallingIdentity(origId);
9815 private final void moveTaskBackwardsLocked(int task) {
9816 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9820 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9821 IActivityContainerCallback callback) throws RemoteException {
9822 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9823 synchronized (this) {
9824 if (parentActivityToken == null) {
9825 throw new IllegalArgumentException("parent token must not be null");
9827 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9831 if (callback == null) {
9832 throw new IllegalArgumentException("callback must not be null");
9834 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9839 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9840 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9841 synchronized (this) {
9842 mStackSupervisor.deleteActivityContainer(container);
9847 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9848 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9849 synchronized (this) {
9850 final int stackId = mStackSupervisor.getNextStackId();
9851 final ActivityStack stack =
9852 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9853 if (stack == null) {
9856 return stack.mActivityContainer;
9861 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9862 synchronized (this) {
9863 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9864 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9865 return stack.mActivityContainer.getDisplayId();
9867 return Display.DEFAULT_DISPLAY;
9872 public int getActivityStackId(IBinder token) throws RemoteException {
9873 synchronized (this) {
9874 ActivityStack stack = ActivityRecord.getStackLocked(token);
9875 if (stack == null) {
9876 return INVALID_STACK_ID;
9878 return stack.mStackId;
9883 public void exitFreeformMode(IBinder token) throws RemoteException {
9884 synchronized (this) {
9885 long ident = Binder.clearCallingIdentity();
9887 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9889 throw new IllegalArgumentException(
9890 "exitFreeformMode: No activity record matching token=" + token);
9892 final ActivityStack stack = r.getStackLocked(token);
9893 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9894 throw new IllegalStateException(
9895 "exitFreeformMode: You can only go fullscreen from freeform.");
9897 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9898 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9899 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9901 Binder.restoreCallingIdentity(ident);
9907 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9908 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9909 if (stackId == HOME_STACK_ID) {
9910 throw new IllegalArgumentException(
9911 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9913 synchronized (this) {
9914 long ident = Binder.clearCallingIdentity();
9916 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9917 + " to stackId=" + stackId + " toTop=" + toTop);
9918 if (stackId == DOCKED_STACK_ID) {
9919 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9920 null /* initialBounds */);
9922 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9923 !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9924 if (result && stackId == DOCKED_STACK_ID) {
9925 // If task moved to docked stack - show recents if needed.
9926 mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9927 "moveTaskToDockedStack");
9930 Binder.restoreCallingIdentity(ident);
9936 public void swapDockedAndFullscreenStack() throws RemoteException {
9937 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9938 synchronized (this) {
9939 long ident = Binder.clearCallingIdentity();
9941 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9942 FULLSCREEN_WORKSPACE_STACK_ID);
9943 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9945 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9946 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9948 if (topTask == null || tasks == null || tasks.size() == 0) {
9950 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9954 // TODO: App transition
9955 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9957 // Defer the resume so resume/pausing while moving stacks is dangerous.
9958 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9959 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9960 ANIMATE, true /* deferResume */);
9961 final int size = tasks.size();
9962 for (int i = 0; i < size; i++) {
9963 final int id = tasks.get(i).taskId;
9964 if (id == topTask.taskId) {
9967 mStackSupervisor.moveTaskToStackLocked(id,
9968 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9969 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9972 // Because we deferred the resume, to avoid conflicts with stack switches while
9973 // resuming, we need to do it after all the tasks are moved.
9974 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9975 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9977 mWindowManager.executeAppTransition();
9979 Binder.restoreCallingIdentity(ident);
9985 * Moves the input task to the docked stack.
9987 * @param taskId Id of task to move.
9988 * @param createMode The mode the docked stack should be created in if it doesn't exist
9990 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9992 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9993 * @param toTop If the task and stack should be moved to the top.
9994 * @param animate Whether we should play an animation for the moving the task
9995 * @param initialBounds If the docked stack gets created, it will use these bounds for the
9996 * docked stack. Pass {@code null} to use default bounds.
9999 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10000 Rect initialBounds, boolean moveHomeStackFront) {
10001 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10002 synchronized (this) {
10003 long ident = Binder.clearCallingIdentity();
10005 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10006 + " to createMode=" + createMode + " toTop=" + toTop);
10007 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10008 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10009 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10010 animate, DEFER_RESUME);
10012 if (moveHomeStackFront) {
10013 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10015 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10019 Binder.restoreCallingIdentity(ident);
10025 * Moves the top activity in the input stackId to the pinned stack.
10027 * @param stackId Id of stack to move the top activity to pinned stack.
10028 * @param bounds Bounds to use for pinned stack.
10030 * @return True if the top activity of the input stack was successfully moved to the pinned
10034 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10035 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10036 synchronized (this) {
10037 if (!mSupportsPictureInPicture) {
10038 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10039 + "Device doesn't support picture-in-pciture mode");
10042 long ident = Binder.clearCallingIdentity();
10044 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10046 Binder.restoreCallingIdentity(ident);
10052 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10053 boolean preserveWindows, boolean animate, int animationDuration) {
10054 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10055 long ident = Binder.clearCallingIdentity();
10057 synchronized (this) {
10059 if (stackId == PINNED_STACK_ID) {
10060 mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10062 throw new IllegalArgumentException("Stack: " + stackId
10063 + " doesn't support animated resize.");
10066 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10067 null /* tempTaskInsetBounds */, preserveWindows,
10068 allowResizeInDockedMode, !DEFER_RESUME);
10072 Binder.restoreCallingIdentity(ident);
10077 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10078 Rect tempDockedTaskInsetBounds,
10079 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10080 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10081 "resizeDockedStack()");
10082 long ident = Binder.clearCallingIdentity();
10084 synchronized (this) {
10085 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10086 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10090 Binder.restoreCallingIdentity(ident);
10095 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10096 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10097 "resizePinnedStack()");
10098 final long ident = Binder.clearCallingIdentity();
10100 synchronized (this) {
10101 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10104 Binder.restoreCallingIdentity(ident);
10109 public void positionTaskInStack(int taskId, int stackId, int position) {
10110 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10111 if (stackId == HOME_STACK_ID) {
10112 throw new IllegalArgumentException(
10113 "positionTaskInStack: Attempt to change the position of task "
10114 + taskId + " in/to home stack");
10116 synchronized (this) {
10117 long ident = Binder.clearCallingIdentity();
10119 if (DEBUG_STACK) Slog.d(TAG_STACK,
10120 "positionTaskInStack: positioning task=" + taskId
10121 + " in stackId=" + stackId + " at position=" + position);
10122 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10124 Binder.restoreCallingIdentity(ident);
10130 public List<StackInfo> getAllStackInfos() {
10131 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10132 long ident = Binder.clearCallingIdentity();
10134 synchronized (this) {
10135 return mStackSupervisor.getAllStackInfosLocked();
10138 Binder.restoreCallingIdentity(ident);
10143 public StackInfo getStackInfo(int stackId) {
10144 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10145 long ident = Binder.clearCallingIdentity();
10147 synchronized (this) {
10148 return mStackSupervisor.getStackInfoLocked(stackId);
10151 Binder.restoreCallingIdentity(ident);
10156 public boolean isInHomeStack(int taskId) {
10157 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10158 long ident = Binder.clearCallingIdentity();
10160 synchronized (this) {
10161 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10162 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10163 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10166 Binder.restoreCallingIdentity(ident);
10171 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10172 synchronized(this) {
10173 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10178 public void updateDeviceOwner(String packageName) {
10179 final int callingUid = Binder.getCallingUid();
10180 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10181 throw new SecurityException("updateDeviceOwner called from non-system process");
10183 synchronized (this) {
10184 mDeviceOwnerName = packageName;
10189 public void updateLockTaskPackages(int userId, String[] packages) {
10190 final int callingUid = Binder.getCallingUid();
10191 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10192 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10193 "updateLockTaskPackages()");
10195 synchronized (this) {
10196 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10197 Arrays.toString(packages));
10198 mLockTaskPackages.put(userId, packages);
10199 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10204 void startLockTaskModeLocked(TaskRecord task) {
10205 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10206 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10210 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10211 // is initiated by system after the pinning request was shown and locked mode is initiated
10212 // by an authorized app directly
10213 final int callingUid = Binder.getCallingUid();
10214 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10215 long ident = Binder.clearCallingIdentity();
10217 if (!isSystemInitiated) {
10218 task.mLockTaskUid = callingUid;
10219 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10220 // startLockTask() called by app and task mode is lockTaskModeDefault.
10221 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10222 StatusBarManagerInternal statusBarManager =
10223 LocalServices.getService(StatusBarManagerInternal.class);
10224 if (statusBarManager != null) {
10225 statusBarManager.showScreenPinningRequest(task.taskId);
10230 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10231 if (stack == null || task != stack.topTask()) {
10232 throw new IllegalArgumentException("Invalid task, not in foreground");
10235 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10237 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10238 ActivityManager.LOCK_TASK_MODE_PINNED :
10239 ActivityManager.LOCK_TASK_MODE_LOCKED,
10240 "startLockTask", true);
10242 Binder.restoreCallingIdentity(ident);
10247 public void startLockTaskMode(int taskId) {
10248 synchronized (this) {
10249 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10250 if (task != null) {
10251 startLockTaskModeLocked(task);
10257 public void startLockTaskMode(IBinder token) {
10258 synchronized (this) {
10259 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10263 final TaskRecord task = r.task;
10264 if (task != null) {
10265 startLockTaskModeLocked(task);
10271 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10272 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10273 // This makes inner call to look as if it was initiated by system.
10274 long ident = Binder.clearCallingIdentity();
10276 synchronized (this) {
10277 startLockTaskMode(taskId);
10280 Binder.restoreCallingIdentity(ident);
10285 public void stopLockTaskMode() {
10286 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10287 if (lockTask == null) {
10288 // Our work here is done.
10292 final int callingUid = Binder.getCallingUid();
10293 final int lockTaskUid = lockTask.mLockTaskUid;
10294 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10295 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10299 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10300 // It is possible lockTaskMode was started by the system process because
10301 // android:lockTaskMode is set to a locking value in the application manifest
10302 // instead of the app calling startLockTaskMode. In this case
10303 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10304 // {@link TaskRecord.effectiveUid} instead. Also caller with
10305 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10306 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10307 && callingUid != lockTaskUid
10308 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10309 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10310 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10313 long ident = Binder.clearCallingIdentity();
10315 Log.d(TAG, "stopLockTaskMode");
10317 synchronized (this) {
10318 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10319 "stopLockTask", true);
10321 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10323 tm.showInCallScreen(false);
10326 Binder.restoreCallingIdentity(ident);
10331 * This API should be called by SystemUI only when user perform certain action to dismiss
10332 * lock task mode. We should only dismiss pinned lock task mode in this case.
10335 public void stopSystemLockTaskMode() throws RemoteException {
10336 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10337 stopLockTaskMode();
10339 mStackSupervisor.showLockTaskToast();
10344 public boolean isInLockTaskMode() {
10345 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10349 public int getLockTaskModeState() {
10350 synchronized (this) {
10351 return mStackSupervisor.getLockTaskModeState();
10356 public void showLockTaskEscapeMessage(IBinder token) {
10357 synchronized (this) {
10358 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10362 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10366 // =========================================================
10367 // CONTENT PROVIDERS
10368 // =========================================================
10370 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10371 List<ProviderInfo> providers = null;
10373 providers = AppGlobals.getPackageManager()
10374 .queryContentProviders(app.processName, app.uid,
10375 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10376 | MATCH_DEBUG_TRIAGED_MISSING)
10378 } catch (RemoteException ex) {
10380 if (DEBUG_MU) Slog.v(TAG_MU,
10381 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10382 int userId = app.userId;
10383 if (providers != null) {
10384 int N = providers.size();
10385 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10386 for (int i=0; i<N; i++) {
10387 // TODO: keep logic in sync with installEncryptionUnawareProviders
10389 (ProviderInfo)providers.get(i);
10390 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10391 cpi.name, cpi.flags);
10392 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10393 // This is a singleton provider, but a user besides the
10394 // default user is asking to initialize a process it runs
10395 // in... well, no, it doesn't actually run in this process,
10396 // it runs in the process of the default user. Get rid of it.
10397 providers.remove(i);
10403 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10404 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10406 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10407 mProviderMap.putProviderByClass(comp, cpr);
10409 if (DEBUG_MU) Slog.v(TAG_MU,
10410 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10411 app.pubProviders.put(cpi.name, cpr);
10412 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10413 // Don't add this if it is a platform component that is marked
10414 // to run in multiple processes, because this is actually
10415 // part of the framework so doesn't make sense to track as a
10416 // separate apk in the process.
10417 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10420 notifyPackageUse(cpi.applicationInfo.packageName,
10421 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10428 * Check if the calling UID has a possible chance at accessing the provider
10429 * at the given authority and user.
10431 public String checkContentProviderAccess(String authority, int userId) {
10432 if (userId == UserHandle.USER_ALL) {
10433 mContext.enforceCallingOrSelfPermission(
10434 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10435 userId = UserHandle.getCallingUserId();
10438 ProviderInfo cpi = null;
10440 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10441 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10442 | PackageManager.MATCH_DIRECT_BOOT_AWARE
10443 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10445 } catch (RemoteException ignored) {
10448 // TODO: make this an outright failure in a future platform release;
10449 // until then anonymous content notifications are unprotected
10450 //return "Failed to find provider " + authority + " for user " + userId;
10454 ProcessRecord r = null;
10455 synchronized (mPidsSelfLocked) {
10456 r = mPidsSelfLocked.get(Binder.getCallingPid());
10459 return "Failed to find PID " + Binder.getCallingPid();
10462 synchronized (this) {
10463 return checkContentProviderPermissionLocked(cpi, r, userId, true);
10468 * Check if {@link ProcessRecord} has a possible chance at accessing the
10469 * given {@link ProviderInfo}. Final permission checking is always done
10470 * in {@link ContentProvider}.
10472 private final String checkContentProviderPermissionLocked(
10473 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10474 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10475 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10476 boolean checkedGrants = false;
10478 // Looking for cross-user grants before enforcing the typical cross-users permissions
10479 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10480 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10481 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10484 checkedGrants = true;
10486 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10487 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10488 if (userId != tmpTargetUserId) {
10489 // When we actually went to determine the final targer user ID, this ended
10490 // up different than our initial check for the authority. This is because
10491 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10492 // SELF. So we need to re-check the grants again.
10493 checkedGrants = false;
10496 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10497 cpi.applicationInfo.uid, cpi.exported)
10498 == PackageManager.PERMISSION_GRANTED) {
10501 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10502 cpi.applicationInfo.uid, cpi.exported)
10503 == PackageManager.PERMISSION_GRANTED) {
10507 PathPermission[] pps = cpi.pathPermissions;
10509 int i = pps.length;
10512 PathPermission pp = pps[i];
10513 String pprperm = pp.getReadPermission();
10514 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10515 cpi.applicationInfo.uid, cpi.exported)
10516 == PackageManager.PERMISSION_GRANTED) {
10519 String ppwperm = pp.getWritePermission();
10520 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10521 cpi.applicationInfo.uid, cpi.exported)
10522 == PackageManager.PERMISSION_GRANTED) {
10527 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10532 if (!cpi.exported) {
10533 msg = "Permission Denial: opening provider " + cpi.name
10534 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10535 + ", uid=" + callingUid + ") that is not exported from uid "
10536 + cpi.applicationInfo.uid;
10538 msg = "Permission Denial: opening provider " + cpi.name
10539 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10540 + ", uid=" + callingUid + ") requires "
10541 + cpi.readPermission + " or " + cpi.writePermission;
10548 * Returns if the ContentProvider has granted a uri to callingUid
10550 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10551 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10552 if (perms != null) {
10553 for (int i=perms.size()-1; i>=0; i--) {
10554 GrantUri grantUri = perms.keyAt(i);
10555 if (grantUri.sourceUserId == userId || !checkUser) {
10556 if (matchesProvider(grantUri.uri, cpi)) {
10566 * Returns true if the uri authority is one of the authorities specified in the provider.
10568 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10569 String uriAuth = uri.getAuthority();
10570 String cpiAuth = cpi.authority;
10571 if (cpiAuth.indexOf(';') == -1) {
10572 return cpiAuth.equals(uriAuth);
10574 String[] cpiAuths = cpiAuth.split(";");
10575 int length = cpiAuths.length;
10576 for (int i = 0; i < length; i++) {
10577 if (cpiAuths[i].equals(uriAuth)) return true;
10582 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10583 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10585 for (int i=0; i<r.conProviders.size(); i++) {
10586 ContentProviderConnection conn = r.conProviders.get(i);
10587 if (conn.provider == cpr) {
10588 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10589 "Adding provider requested by "
10590 + r.processName + " from process "
10591 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10592 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10594 conn.stableCount++;
10595 conn.numStableIncs++;
10597 conn.unstableCount++;
10598 conn.numUnstableIncs++;
10603 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10605 conn.stableCount = 1;
10606 conn.numStableIncs = 1;
10608 conn.unstableCount = 1;
10609 conn.numUnstableIncs = 1;
10611 cpr.connections.add(conn);
10612 r.conProviders.add(conn);
10613 startAssociationLocked(r.uid, r.processName, r.curProcState,
10614 cpr.uid, cpr.name, cpr.info.processName);
10617 cpr.addExternalProcessHandleLocked(externalProcessToken);
10621 boolean decProviderCountLocked(ContentProviderConnection conn,
10622 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10623 if (conn != null) {
10624 cpr = conn.provider;
10625 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10626 "Removing provider requested by "
10627 + conn.client.processName + " from process "
10628 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10629 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10631 conn.stableCount--;
10633 conn.unstableCount--;
10635 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10636 cpr.connections.remove(conn);
10637 conn.client.conProviders.remove(conn);
10638 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10639 // The client is more important than last activity -- note the time this
10640 // is happening, so we keep the old provider process around a bit as last
10641 // activity to avoid thrashing it.
10642 if (cpr.proc != null) {
10643 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10646 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10651 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10655 private void checkTime(long startTime, String where) {
10656 long now = SystemClock.uptimeMillis();
10657 if ((now-startTime) > 50) {
10658 // If we are taking more than 50ms, log about it.
10659 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10663 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10665 PROC_SPACE_TERM|PROC_PARENS,
10666 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
10669 private final long[] mProcessStateStatsLongs = new long[1];
10671 boolean isProcessAliveLocked(ProcessRecord proc) {
10672 if (proc.procStatFile == null) {
10673 proc.procStatFile = "/proc/" + proc.pid + "/stat";
10675 mProcessStateStatsLongs[0] = 0;
10676 if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10677 mProcessStateStatsLongs, null)) {
10678 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10681 final long state = mProcessStateStatsLongs[0];
10682 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10684 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10687 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10688 String name, IBinder token, boolean stable, int userId) {
10689 ContentProviderRecord cpr;
10690 ContentProviderConnection conn = null;
10691 ProviderInfo cpi = null;
10693 synchronized(this) {
10694 long startTime = SystemClock.uptimeMillis();
10696 ProcessRecord r = null;
10697 if (caller != null) {
10698 r = getRecordForAppLocked(caller);
10700 throw new SecurityException(
10701 "Unable to find app for caller " + caller
10702 + " (pid=" + Binder.getCallingPid()
10703 + ") when getting content provider " + name);
10707 boolean checkCrossUser = true;
10709 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10711 // First check if this content provider has been published...
10712 cpr = mProviderMap.getProviderByName(name, userId);
10713 // If that didn't work, check if it exists for user 0 and then
10714 // verify that it's a singleton provider before using it.
10715 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10716 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10719 if (isSingleton(cpi.processName, cpi.applicationInfo,
10720 cpi.name, cpi.flags)
10721 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10722 userId = UserHandle.USER_SYSTEM;
10723 checkCrossUser = false;
10731 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10732 if (providerRunning) {
10735 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10736 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10738 throw new SecurityException(msg);
10740 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10742 if (r != null && cpr.canRunHere(r)) {
10743 // This provider has been published or is in the process
10744 // of being published... but it is also allowed to run
10745 // in the caller's process, so don't make a connection
10746 // and just let the caller instantiate its own instance.
10747 ContentProviderHolder holder = cpr.newHolder(null);
10748 // don't give caller the provider object, it needs
10749 // to make its own.
10750 holder.provider = null;
10754 final long origId = Binder.clearCallingIdentity();
10756 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10758 // In this case the provider instance already exists, so we can
10759 // return it right away.
10760 conn = incProviderCountLocked(r, cpr, token, stable);
10761 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10762 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10763 // If this is a perceptible app accessing the provider,
10764 // make sure to count it as being accessed and thus
10765 // back up on the LRU list. This is good because
10766 // content providers are often expensive to start.
10767 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10768 updateLruProcessLocked(cpr.proc, false, null);
10769 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10773 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10774 final int verifiedAdj = cpr.proc.verifiedAdj;
10775 boolean success = updateOomAdjLocked(cpr.proc);
10776 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10777 // if the process has been successfully adjusted. So to reduce races with
10778 // it, we will check whether the process still exists. Note that this doesn't
10779 // completely get rid of races with LMK killing the process, but should make
10780 // them much smaller.
10781 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10784 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10785 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10786 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10787 // NOTE: there is still a race here where a signal could be
10788 // pending on the process even though we managed to update its
10789 // adj level. Not sure what to do about this, but at least
10790 // the race is now smaller.
10792 // Uh oh... it looks like the provider's process
10793 // has been killed on us. We need to wait for a new
10794 // process to be started, and make sure its death
10795 // doesn't kill our process.
10796 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10797 + " is crashing; detaching " + r);
10798 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10799 checkTime(startTime, "getContentProviderImpl: before appDied");
10800 appDiedLocked(cpr.proc);
10801 checkTime(startTime, "getContentProviderImpl: after appDied");
10803 // This wasn't the last ref our process had on
10804 // the provider... we have now been killed, bail.
10807 providerRunning = false;
10810 cpr.proc.verifiedAdj = cpr.proc.setAdj;
10813 Binder.restoreCallingIdentity(origId);
10816 if (!providerRunning) {
10818 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10819 cpi = AppGlobals.getPackageManager().
10820 resolveContentProvider(name,
10821 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10822 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10823 } catch (RemoteException ex) {
10828 // If the provider is a singleton AND
10829 // (it's a call within the same user || the provider is a
10831 // Then allow connecting to the singleton provider
10832 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10833 cpi.name, cpi.flags)
10834 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10836 userId = UserHandle.USER_SYSTEM;
10838 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10839 checkTime(startTime, "getContentProviderImpl: got app info for user");
10842 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10843 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10845 throw new SecurityException(msg);
10847 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10849 if (!mProcessesReady
10850 && !cpi.processName.equals("system")) {
10851 // If this content provider does not run in the system
10852 // process, and the system is not yet ready to run other
10853 // processes, then fail fast instead of hanging.
10854 throw new IllegalArgumentException(
10855 "Attempt to launch content provider before system ready");
10858 // Make sure that the user who owns this provider is running. If not,
10859 // we don't want to allow it to run.
10860 if (!mUserController.isUserRunningLocked(userId, 0)) {
10861 Slog.w(TAG, "Unable to launch app "
10862 + cpi.applicationInfo.packageName + "/"
10863 + cpi.applicationInfo.uid + " for provider "
10864 + name + ": user " + userId + " is stopped");
10868 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10869 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10870 cpr = mProviderMap.getProviderByClass(comp, userId);
10871 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10872 final boolean firstClass = cpr == null;
10874 final long ident = Binder.clearCallingIdentity();
10876 // If permissions need a review before any of the app components can run,
10877 // we return no provider and launch a review activity if the calling app
10878 // is in the foreground.
10879 if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10880 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10886 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10887 ApplicationInfo ai =
10888 AppGlobals.getPackageManager().
10889 getApplicationInfo(
10890 cpi.applicationInfo.packageName,
10891 STOCK_PM_FLAGS, userId);
10892 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10894 Slog.w(TAG, "No package info for content provider "
10898 ai = getAppInfoForUser(ai, userId);
10899 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10900 } catch (RemoteException ex) {
10901 // pm is in same process, this will never happen.
10903 Binder.restoreCallingIdentity(ident);
10907 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10909 if (r != null && cpr.canRunHere(r)) {
10910 // If this is a multiprocess provider, then just return its
10911 // info and allow the caller to instantiate it. Only do
10912 // this if the provider is the same user as the caller's
10913 // process, or can run as root (so can be in any process).
10914 return cpr.newHolder(null);
10917 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10918 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10919 + cpr.info.name + " callers=" + Debug.getCallers(6));
10921 // This is single process, and our app is now connecting to it.
10922 // See if we are already in the process of launching this
10924 final int N = mLaunchingProviders.size();
10926 for (i = 0; i < N; i++) {
10927 if (mLaunchingProviders.get(i) == cpr) {
10932 // If the provider is not already being launched, then get it
10935 final long origId = Binder.clearCallingIdentity();
10938 // Content provider is now in use, its package can't be stopped.
10940 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10941 AppGlobals.getPackageManager().setPackageStoppedState(
10942 cpr.appInfo.packageName, false, userId);
10943 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10944 } catch (RemoteException e) {
10945 } catch (IllegalArgumentException e) {
10946 Slog.w(TAG, "Failed trying to unstop package "
10947 + cpr.appInfo.packageName + ": " + e);
10950 // Use existing process if already started
10951 checkTime(startTime, "getContentProviderImpl: looking for process record");
10952 ProcessRecord proc = getProcessRecordLocked(
10953 cpi.processName, cpr.appInfo.uid, false);
10954 if (proc != null && proc.thread != null && !proc.killed) {
10955 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10956 "Installing in existing process " + proc);
10957 if (!proc.pubProviders.containsKey(cpi.name)) {
10958 checkTime(startTime, "getContentProviderImpl: scheduling install");
10959 proc.pubProviders.put(cpi.name, cpr);
10961 proc.thread.scheduleInstallProvider(cpi);
10962 } catch (RemoteException e) {
10966 checkTime(startTime, "getContentProviderImpl: before start process");
10967 proc = startProcessLocked(cpi.processName,
10968 cpr.appInfo, false, 0, "content provider",
10969 new ComponentName(cpi.applicationInfo.packageName,
10970 cpi.name), false, false, false);
10971 checkTime(startTime, "getContentProviderImpl: after start process");
10972 if (proc == null) {
10973 Slog.w(TAG, "Unable to launch app "
10974 + cpi.applicationInfo.packageName + "/"
10975 + cpi.applicationInfo.uid + " for provider "
10976 + name + ": process is bad");
10980 cpr.launchingApp = proc;
10981 mLaunchingProviders.add(cpr);
10983 Binder.restoreCallingIdentity(origId);
10987 checkTime(startTime, "getContentProviderImpl: updating data structures");
10989 // Make sure the provider is published (the same provider class
10990 // may be published under multiple names).
10992 mProviderMap.putProviderByClass(comp, cpr);
10995 mProviderMap.putProviderByName(name, cpr);
10996 conn = incProviderCountLocked(r, cpr, token, stable);
10997 if (conn != null) {
10998 conn.waiting = true;
11001 checkTime(startTime, "getContentProviderImpl: done!");
11004 // Wait for the provider to be published...
11005 synchronized (cpr) {
11006 while (cpr.provider == null) {
11007 if (cpr.launchingApp == null) {
11008 Slog.w(TAG, "Unable to launch app "
11009 + cpi.applicationInfo.packageName + "/"
11010 + cpi.applicationInfo.uid + " for provider "
11011 + name + ": launching app became null");
11012 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11013 UserHandle.getUserId(cpi.applicationInfo.uid),
11014 cpi.applicationInfo.packageName,
11015 cpi.applicationInfo.uid, name);
11019 if (DEBUG_MU) Slog.v(TAG_MU,
11020 "Waiting to start provider " + cpr
11021 + " launchingApp=" + cpr.launchingApp);
11022 if (conn != null) {
11023 conn.waiting = true;
11026 } catch (InterruptedException ex) {
11028 if (conn != null) {
11029 conn.waiting = false;
11034 return cpr != null ? cpr.newHolder(conn) : null;
11037 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11038 ProcessRecord r, final int userId) {
11039 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11040 cpi.packageName, userId)) {
11042 final boolean callerForeground = r == null || r.setSchedGroup
11043 != ProcessList.SCHED_GROUP_BACKGROUND;
11045 // Show a permission review UI only for starting from a foreground app
11046 if (!callerForeground) {
11047 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11048 + cpi.packageName + " requires a permissions review");
11052 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11053 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11054 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11055 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11057 if (DEBUG_PERMISSIONS_REVIEW) {
11058 Slog.i(TAG, "u" + userId + " Launching permission review "
11059 + "for package " + cpi.packageName);
11062 final UserHandle userHandle = new UserHandle(userId);
11063 mHandler.post(new Runnable() {
11065 public void run() {
11066 mContext.startActivityAsUser(intent, userHandle);
11076 PackageManagerInternal getPackageManagerInternalLocked() {
11077 if (mPackageManagerInt == null) {
11078 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11080 return mPackageManagerInt;
11084 public final ContentProviderHolder getContentProvider(
11085 IApplicationThread caller, String name, int userId, boolean stable) {
11086 enforceNotIsolatedCaller("getContentProvider");
11087 if (caller == null) {
11088 String msg = "null IApplicationThread when getting content provider "
11091 throw new SecurityException(msg);
11093 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11094 // with cross-user grant.
11095 return getContentProviderImpl(caller, name, null, stable, userId);
11098 public ContentProviderHolder getContentProviderExternal(
11099 String name, int userId, IBinder token) {
11100 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11101 "Do not have permission in call getContentProviderExternal()");
11102 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11103 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11104 return getContentProviderExternalUnchecked(name, token, userId);
11107 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11108 IBinder token, int userId) {
11109 return getContentProviderImpl(null, name, token, true, userId);
11113 * Drop a content provider from a ProcessRecord's bookkeeping
11115 public void removeContentProvider(IBinder connection, boolean stable) {
11116 enforceNotIsolatedCaller("removeContentProvider");
11117 long ident = Binder.clearCallingIdentity();
11119 synchronized (this) {
11120 ContentProviderConnection conn;
11122 conn = (ContentProviderConnection)connection;
11123 } catch (ClassCastException e) {
11124 String msg ="removeContentProvider: " + connection
11125 + " not a ContentProviderConnection";
11127 throw new IllegalArgumentException(msg);
11129 if (conn == null) {
11130 throw new NullPointerException("connection is null");
11132 if (decProviderCountLocked(conn, null, null, stable)) {
11133 updateOomAdjLocked();
11137 Binder.restoreCallingIdentity(ident);
11141 public void removeContentProviderExternal(String name, IBinder token) {
11142 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11143 "Do not have permission in call removeContentProviderExternal()");
11144 int userId = UserHandle.getCallingUserId();
11145 long ident = Binder.clearCallingIdentity();
11147 removeContentProviderExternalUnchecked(name, token, userId);
11149 Binder.restoreCallingIdentity(ident);
11153 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11154 synchronized (this) {
11155 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11157 //remove from mProvidersByClass
11158 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11162 //update content provider record entry info
11163 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11164 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11165 if (localCpr.hasExternalProcessHandles()) {
11166 if (localCpr.removeExternalProcessHandleLocked(token)) {
11167 updateOomAdjLocked();
11169 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11170 + " with no external reference for token: "
11174 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11175 + " with no external references.");
11180 public final void publishContentProviders(IApplicationThread caller,
11181 List<ContentProviderHolder> providers) {
11182 if (providers == null) {
11186 enforceNotIsolatedCaller("publishContentProviders");
11187 synchronized (this) {
11188 final ProcessRecord r = getRecordForAppLocked(caller);
11189 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11191 throw new SecurityException(
11192 "Unable to find app for caller " + caller
11193 + " (pid=" + Binder.getCallingPid()
11194 + ") when publishing content providers");
11197 final long origId = Binder.clearCallingIdentity();
11199 final int N = providers.size();
11200 for (int i = 0; i < N; i++) {
11201 ContentProviderHolder src = providers.get(i);
11202 if (src == null || src.info == null || src.provider == null) {
11205 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11206 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11208 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11209 mProviderMap.putProviderByClass(comp, dst);
11210 String names[] = dst.info.authority.split(";");
11211 for (int j = 0; j < names.length; j++) {
11212 mProviderMap.putProviderByName(names[j], dst);
11215 int launchingCount = mLaunchingProviders.size();
11217 boolean wasInLaunchingProviders = false;
11218 for (j = 0; j < launchingCount; j++) {
11219 if (mLaunchingProviders.get(j) == dst) {
11220 mLaunchingProviders.remove(j);
11221 wasInLaunchingProviders = true;
11226 if (wasInLaunchingProviders) {
11227 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11229 synchronized (dst) {
11230 dst.provider = src.provider;
11234 updateOomAdjLocked(r);
11235 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11236 src.info.authority);
11240 Binder.restoreCallingIdentity(origId);
11244 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11245 ContentProviderConnection conn;
11247 conn = (ContentProviderConnection)connection;
11248 } catch (ClassCastException e) {
11249 String msg ="refContentProvider: " + connection
11250 + " not a ContentProviderConnection";
11252 throw new IllegalArgumentException(msg);
11254 if (conn == null) {
11255 throw new NullPointerException("connection is null");
11258 synchronized (this) {
11260 conn.numStableIncs += stable;
11262 stable = conn.stableCount + stable;
11264 throw new IllegalStateException("stableCount < 0: " + stable);
11267 if (unstable > 0) {
11268 conn.numUnstableIncs += unstable;
11270 unstable = conn.unstableCount + unstable;
11271 if (unstable < 0) {
11272 throw new IllegalStateException("unstableCount < 0: " + unstable);
11275 if ((stable+unstable) <= 0) {
11276 throw new IllegalStateException("ref counts can't go to zero here: stable="
11277 + stable + " unstable=" + unstable);
11279 conn.stableCount = stable;
11280 conn.unstableCount = unstable;
11285 public void unstableProviderDied(IBinder connection) {
11286 ContentProviderConnection conn;
11288 conn = (ContentProviderConnection)connection;
11289 } catch (ClassCastException e) {
11290 String msg ="refContentProvider: " + connection
11291 + " not a ContentProviderConnection";
11293 throw new IllegalArgumentException(msg);
11295 if (conn == null) {
11296 throw new NullPointerException("connection is null");
11299 // Safely retrieve the content provider associated with the connection.
11300 IContentProvider provider;
11301 synchronized (this) {
11302 provider = conn.provider.provider;
11305 if (provider == null) {
11306 // Um, yeah, we're way ahead of you.
11310 // Make sure the caller is being honest with us.
11311 if (provider.asBinder().pingBinder()) {
11312 // Er, no, still looks good to us.
11313 synchronized (this) {
11314 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11315 + " says " + conn + " died, but we don't agree");
11320 // Well look at that! It's dead!
11321 synchronized (this) {
11322 if (conn.provider.provider != provider) {
11323 // But something changed... good enough.
11327 ProcessRecord proc = conn.provider.proc;
11328 if (proc == null || proc.thread == null) {
11329 // Seems like the process is already cleaned up.
11333 // As far as we're concerned, this is just like receiving a
11334 // death notification... just a bit prematurely.
11335 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11336 + ") early provider death");
11337 final long ident = Binder.clearCallingIdentity();
11339 appDiedLocked(proc);
11341 Binder.restoreCallingIdentity(ident);
11347 public void appNotRespondingViaProvider(IBinder connection) {
11348 enforceCallingPermission(
11349 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11351 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11352 if (conn == null) {
11353 Slog.w(TAG, "ContentProviderConnection is null");
11357 final ProcessRecord host = conn.provider.proc;
11358 if (host == null) {
11359 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11363 mHandler.post(new Runnable() {
11365 public void run() {
11366 mAppErrors.appNotResponding(host, null, null, false,
11367 "ContentProvider not responding");
11372 public final void installSystemProviders() {
11373 List<ProviderInfo> providers;
11374 synchronized (this) {
11375 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11376 providers = generateApplicationProvidersLocked(app);
11377 if (providers != null) {
11378 for (int i=providers.size()-1; i>=0; i--) {
11379 ProviderInfo pi = (ProviderInfo)providers.get(i);
11380 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11381 Slog.w(TAG, "Not installing system proc provider " + pi.name
11382 + ": not system .apk");
11383 providers.remove(i);
11388 if (providers != null) {
11389 mSystemThread.installSystemProviders(providers);
11392 mCoreSettingsObserver = new CoreSettingsObserver(this);
11393 mFontScaleSettingObserver = new FontScaleSettingObserver();
11395 //mUsageStatsService.monitorPackages();
11398 private void startPersistentApps(int matchFlags) {
11399 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11401 synchronized (this) {
11403 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11404 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11405 for (ApplicationInfo app : apps) {
11406 if (!"android".equals(app.packageName)) {
11407 addAppLocked(app, false, null /* ABI override */);
11410 } catch (RemoteException ex) {
11416 * When a user is unlocked, we need to install encryption-unaware providers
11417 * belonging to any running apps.
11419 private void installEncryptionUnawareProviders(int userId) {
11420 // We're only interested in providers that are encryption unaware, and
11421 // we don't care about uninstalled apps, since there's no way they're
11422 // running at this point.
11423 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11425 synchronized (this) {
11426 final int NP = mProcessNames.getMap().size();
11427 for (int ip = 0; ip < NP; ip++) {
11428 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11429 final int NA = apps.size();
11430 for (int ia = 0; ia < NA; ia++) {
11431 final ProcessRecord app = apps.valueAt(ia);
11432 if (app.userId != userId || app.thread == null || app.unlocked) continue;
11434 final int NG = app.pkgList.size();
11435 for (int ig = 0; ig < NG; ig++) {
11437 final String pkgName = app.pkgList.keyAt(ig);
11438 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11439 .getPackageInfo(pkgName, matchFlags, userId);
11440 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11441 for (ProviderInfo pi : pkgInfo.providers) {
11442 // TODO: keep in sync with generateApplicationProvidersLocked
11443 final boolean processMatch = Objects.equals(pi.processName,
11444 app.processName) || pi.multiprocess;
11445 final boolean userMatch = isSingleton(pi.processName,
11446 pi.applicationInfo, pi.name, pi.flags)
11447 ? (app.userId == UserHandle.USER_SYSTEM) : true;
11448 if (processMatch && userMatch) {
11449 Log.v(TAG, "Installing " + pi);
11450 app.thread.scheduleInstallProvider(pi);
11452 Log.v(TAG, "Skipping " + pi);
11456 } catch (RemoteException ignored) {
11465 * Allows apps to retrieve the MIME type of a URI.
11466 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11467 * users, then it does not need permission to access the ContentProvider.
11468 * Either, it needs cross-user uri grants.
11470 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11472 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11473 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11475 public String getProviderMimeType(Uri uri, int userId) {
11476 enforceNotIsolatedCaller("getProviderMimeType");
11477 final String name = uri.getAuthority();
11478 int callingUid = Binder.getCallingUid();
11479 int callingPid = Binder.getCallingPid();
11481 boolean clearedIdentity = false;
11482 synchronized (this) {
11483 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11485 if (canClearIdentity(callingPid, callingUid, userId)) {
11486 clearedIdentity = true;
11487 ident = Binder.clearCallingIdentity();
11489 ContentProviderHolder holder = null;
11491 holder = getContentProviderExternalUnchecked(name, null, userId);
11492 if (holder != null) {
11493 return holder.provider.getType(uri);
11495 } catch (RemoteException e) {
11496 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11498 } catch (Exception e) {
11499 Log.w(TAG, "Exception while determining type of " + uri, e);
11502 // We need to clear the identity to call removeContentProviderExternalUnchecked
11503 if (!clearedIdentity) {
11504 ident = Binder.clearCallingIdentity();
11507 if (holder != null) {
11508 removeContentProviderExternalUnchecked(name, null, userId);
11511 Binder.restoreCallingIdentity(ident);
11518 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11519 if (UserHandle.getUserId(callingUid) == userId) {
11522 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11523 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11524 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11525 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11531 // =========================================================
11532 // GLOBAL MANAGEMENT
11533 // =========================================================
11535 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11536 boolean isolated, int isolatedUid) {
11537 String proc = customProcess != null ? customProcess : info.processName;
11538 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11539 final int userId = UserHandle.getUserId(info.uid);
11540 int uid = info.uid;
11542 if (isolatedUid == 0) {
11543 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11545 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11546 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11547 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11549 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11550 mNextIsolatedProcessUid++;
11551 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11552 // No process for this uid, use it.
11556 if (stepsLeft <= 0) {
11561 // Special case for startIsolatedProcess (internal only), where
11562 // the uid of the isolated process is specified by the caller.
11566 // Register the isolated UID with this application so BatteryStats knows to
11567 // attribute resource usage to the application.
11569 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11570 // about the process state of the isolated UID *before* it is registered with the
11571 // owning application.
11572 mBatteryStatsService.addIsolatedUid(uid, info.uid);
11574 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11575 if (!mBooted && !mBooting
11576 && userId == UserHandle.USER_SYSTEM
11577 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11578 r.persistent = true;
11580 addProcessNameLocked(r);
11584 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11585 String abiOverride) {
11588 app = getProcessRecordLocked(info.processName, info.uid, true);
11594 app = newProcessRecordLocked(info, null, isolated, 0);
11595 updateLruProcessLocked(app, false, null);
11596 updateOomAdjLocked();
11599 // This package really, really can not be stopped.
11601 AppGlobals.getPackageManager().setPackageStoppedState(
11602 info.packageName, false, UserHandle.getUserId(app.uid));
11603 } catch (RemoteException e) {
11604 } catch (IllegalArgumentException e) {
11605 Slog.w(TAG, "Failed trying to unstop package "
11606 + info.packageName + ": " + e);
11609 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11610 app.persistent = true;
11611 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11613 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11614 mPersistentStartingProcesses.add(app);
11615 startProcessLocked(app, "added application", app.processName, abiOverride,
11616 null /* entryPoint */, null /* entryPointArgs */);
11622 public void unhandledBack() {
11623 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11624 "unhandledBack()");
11626 synchronized(this) {
11627 final long origId = Binder.clearCallingIdentity();
11629 getFocusedStack().unhandledBackLocked();
11631 Binder.restoreCallingIdentity(origId);
11636 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11637 enforceNotIsolatedCaller("openContentUri");
11638 final int userId = UserHandle.getCallingUserId();
11639 String name = uri.getAuthority();
11640 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11641 ParcelFileDescriptor pfd = null;
11643 // We record the binder invoker's uid in thread-local storage before
11644 // going to the content provider to open the file. Later, in the code
11645 // that handles all permissions checks, we look for this uid and use
11646 // that rather than the Activity Manager's own uid. The effect is that
11647 // we do the check against the caller's permissions even though it looks
11648 // to the content provider like the Activity Manager itself is making
11650 Binder token = new Binder();
11651 sCallerIdentity.set(new Identity(
11652 token, Binder.getCallingPid(), Binder.getCallingUid()));
11654 pfd = cph.provider.openFile(null, uri, "r", null, token);
11655 } catch (FileNotFoundException e) {
11656 // do nothing; pfd will be returned null
11658 // Ensure that whatever happens, we clean up the identity state
11659 sCallerIdentity.remove();
11660 // Ensure we're done with the provider.
11661 removeContentProviderExternalUnchecked(name, null, userId);
11664 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11669 // Actually is sleeping or shutting down or whatever else in the future
11670 // is an inactive state.
11671 boolean isSleepingOrShuttingDownLocked() {
11672 return isSleepingLocked() || mShuttingDown;
11675 boolean isShuttingDownLocked() {
11676 return mShuttingDown;
11679 boolean isSleepingLocked() {
11683 void onWakefulnessChanged(int wakefulness) {
11684 synchronized(this) {
11685 mWakefulness = wakefulness;
11686 updateSleepIfNeededLocked();
11690 void finishRunningVoiceLocked() {
11691 if (mRunningVoice != null) {
11692 mRunningVoice = null;
11693 mVoiceWakeLock.release();
11694 updateSleepIfNeededLocked();
11698 void startTimeTrackingFocusedActivityLocked() {
11699 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11700 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11704 void updateSleepIfNeededLocked() {
11705 if (mSleeping && !shouldSleepLocked()) {
11707 startTimeTrackingFocusedActivityLocked();
11708 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11709 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11710 sendNotifyVrManagerOfSleepState(false);
11711 updateOomAdjLocked();
11712 } else if (!mSleeping && shouldSleepLocked()) {
11714 if (mCurAppTimeTracker != null) {
11715 mCurAppTimeTracker.stop();
11717 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11718 mStackSupervisor.goingToSleepLocked();
11719 sendNotifyVrManagerOfSleepState(true);
11720 updateOomAdjLocked();
11722 // Initialize the wake times of all processes.
11723 checkExcessivePowerUsageLocked(false);
11724 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11725 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11726 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11730 private boolean shouldSleepLocked() {
11731 // Resume applications while running a voice interactor.
11732 if (mRunningVoice != null) {
11736 // TODO: Transform the lock screen state into a sleep token instead.
11737 switch (mWakefulness) {
11738 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11739 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11740 case PowerManagerInternal.WAKEFULNESS_DOZING:
11741 // Pause applications whenever the lock screen is shown or any sleep
11742 // tokens have been acquired.
11743 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11744 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11746 // If we're asleep then pause applications unconditionally.
11751 /** Pokes the task persister. */
11752 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11753 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11756 /** Notifies all listeners when the task stack has changed. */
11757 void notifyTaskStackChangedLocked() {
11758 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11759 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11760 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11761 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11764 /** Notifies all listeners when an Activity is pinned. */
11765 void notifyActivityPinnedLocked() {
11766 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11767 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11771 * Notifies all listeners when an attempt was made to start an an activity that is already
11772 * running in the pinned stack and the activity was not actually started, but the task is
11773 * either brought to the front or a new Intent is delivered to it.
11775 void notifyPinnedActivityRestartAttemptLocked() {
11776 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11777 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11780 /** Notifies all listeners when the pinned stack animation ends. */
11782 public void notifyPinnedStackAnimationEnded() {
11783 synchronized (this) {
11784 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11785 mHandler.obtainMessage(
11786 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11791 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11792 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11796 public boolean shutdown(int timeout) {
11797 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11798 != PackageManager.PERMISSION_GRANTED) {
11799 throw new SecurityException("Requires permission "
11800 + android.Manifest.permission.SHUTDOWN);
11803 boolean timedout = false;
11805 synchronized(this) {
11806 mShuttingDown = true;
11807 updateEventDispatchingLocked();
11808 timedout = mStackSupervisor.shutdownLocked(timeout);
11811 mAppOpsService.shutdown();
11812 if (mUsageStatsService != null) {
11813 mUsageStatsService.prepareShutdown();
11815 mBatteryStatsService.shutdown();
11816 synchronized (this) {
11817 mProcessStats.shutdownLocked();
11818 notifyTaskPersisterLocked(null, true);
11824 public final void activitySlept(IBinder token) {
11825 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11827 final long origId = Binder.clearCallingIdentity();
11829 synchronized (this) {
11830 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11832 mStackSupervisor.activitySleptLocked(r);
11836 Binder.restoreCallingIdentity(origId);
11839 private String lockScreenShownToString() {
11840 switch (mLockScreenShown) {
11841 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11842 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11843 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11844 default: return "Unknown=" + mLockScreenShown;
11848 void logLockScreen(String msg) {
11849 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11850 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11851 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11852 + " mSleeping=" + mSleeping);
11855 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11856 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11857 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11858 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11859 boolean wasRunningVoice = mRunningVoice != null;
11860 mRunningVoice = session;
11861 if (!wasRunningVoice) {
11862 mVoiceWakeLock.acquire();
11863 updateSleepIfNeededLocked();
11868 private void updateEventDispatchingLocked() {
11869 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11872 public void setLockScreenShown(boolean showing, boolean occluded) {
11873 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11874 != PackageManager.PERMISSION_GRANTED) {
11875 throw new SecurityException("Requires permission "
11876 + android.Manifest.permission.DEVICE_POWER);
11879 synchronized(this) {
11880 long ident = Binder.clearCallingIdentity();
11882 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11883 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11884 if (showing && occluded) {
11885 // The lock screen is currently showing, but is occluded by a window that can
11886 // show on top of the lock screen. In this can we want to dismiss the docked
11887 // stack since it will be complicated/risky to try to put the activity on top
11888 // of the lock screen in the right fullscreen configuration.
11889 mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11890 mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11893 updateSleepIfNeededLocked();
11895 Binder.restoreCallingIdentity(ident);
11901 public void notifyLockedProfile(@UserIdInt int userId) {
11903 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11904 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11906 } catch (RemoteException ex) {
11907 throw new SecurityException("Fail to check is caller a privileged app", ex);
11910 synchronized (this) {
11911 if (mStackSupervisor.isUserLockedProfile(userId)) {
11912 final long ident = Binder.clearCallingIdentity();
11914 final int currentUserId = mUserController.getCurrentUserIdLocked();
11916 // Drop locked freeform tasks out into the fullscreen stack.
11917 // TODO: Redact the tasks in place. It's much better to keep them on the screen
11918 // where they were before, but in an obscured state.
11919 mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11921 if (mUserController.isLockScreenDisabled(currentUserId)) {
11922 // If there is no device lock, we will show the profile's credential page.
11923 mActivityStarter.showConfirmDeviceCredential(userId);
11925 // Showing launcher to avoid user entering credential twice.
11926 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11929 Binder.restoreCallingIdentity(ident);
11936 public void startConfirmDeviceCredentialIntent(Intent intent) {
11937 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11938 synchronized (this) {
11939 final long ident = Binder.clearCallingIdentity();
11941 mActivityStarter.startConfirmCredentialIntent(intent);
11943 Binder.restoreCallingIdentity(ident);
11949 public void stopAppSwitches() {
11950 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11951 != PackageManager.PERMISSION_GRANTED) {
11952 throw new SecurityException("viewquires permission "
11953 + android.Manifest.permission.STOP_APP_SWITCHES);
11956 synchronized(this) {
11957 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11958 + APP_SWITCH_DELAY_TIME;
11959 mDidAppSwitch = false;
11960 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11961 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11962 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11966 public void resumeAppSwitches() {
11967 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11968 != PackageManager.PERMISSION_GRANTED) {
11969 throw new SecurityException("Requires permission "
11970 + android.Manifest.permission.STOP_APP_SWITCHES);
11973 synchronized(this) {
11974 // Note that we don't execute any pending app switches... we will
11975 // let those wait until either the timeout, or the next start
11976 // activity request.
11977 mAppSwitchesAllowedTime = 0;
11981 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11982 int callingPid, int callingUid, String name) {
11983 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11987 int perm = checkComponentPermission(
11988 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11989 sourceUid, -1, true);
11990 if (perm == PackageManager.PERMISSION_GRANTED) {
11994 // If the actual IPC caller is different from the logical source, then
11995 // also see if they are allowed to control app switches.
11996 if (callingUid != -1 && callingUid != sourceUid) {
11997 perm = checkComponentPermission(
11998 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11999 callingUid, -1, true);
12000 if (perm == PackageManager.PERMISSION_GRANTED) {
12005 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12009 public void setDebugApp(String packageName, boolean waitForDebugger,
12010 boolean persistent) {
12011 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12014 long ident = Binder.clearCallingIdentity();
12016 // Note that this is not really thread safe if there are multiple
12017 // callers into it at the same time, but that's not a situation we
12020 final ContentResolver resolver = mContext.getContentResolver();
12021 Settings.Global.putString(
12022 resolver, Settings.Global.DEBUG_APP,
12024 Settings.Global.putInt(
12025 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12026 waitForDebugger ? 1 : 0);
12029 synchronized (this) {
12031 mOrigDebugApp = mDebugApp;
12032 mOrigWaitForDebugger = mWaitForDebugger;
12034 mDebugApp = packageName;
12035 mWaitForDebugger = waitForDebugger;
12036 mDebugTransient = !persistent;
12037 if (packageName != null) {
12038 forceStopPackageLocked(packageName, -1, false, false, true, true,
12039 false, UserHandle.USER_ALL, "set debug app");
12043 Binder.restoreCallingIdentity(ident);
12047 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12048 synchronized (this) {
12049 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12050 if (!isDebuggable) {
12051 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12052 throw new SecurityException("Process not debuggable: " + app.packageName);
12056 mTrackAllocationApp = processName;
12060 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12061 synchronized (this) {
12062 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12063 if (!isDebuggable) {
12064 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12065 throw new SecurityException("Process not debuggable: " + app.packageName);
12068 mProfileApp = processName;
12069 mProfileFile = profilerInfo.profileFile;
12070 if (mProfileFd != null) {
12072 mProfileFd.close();
12073 } catch (IOException e) {
12077 mProfileFd = profilerInfo.profileFd;
12078 mSamplingInterval = profilerInfo.samplingInterval;
12079 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12084 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12085 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12086 if (!isDebuggable) {
12087 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12088 throw new SecurityException("Process not debuggable: " + app.packageName);
12091 mNativeDebuggingApp = processName;
12095 public void setAlwaysFinish(boolean enabled) {
12096 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12097 "setAlwaysFinish()");
12099 long ident = Binder.clearCallingIdentity();
12101 Settings.Global.putInt(
12102 mContext.getContentResolver(),
12103 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12105 synchronized (this) {
12106 mAlwaysFinishActivities = enabled;
12109 Binder.restoreCallingIdentity(ident);
12114 public void setLenientBackgroundCheck(boolean enabled) {
12115 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12116 "setLenientBackgroundCheck()");
12118 long ident = Binder.clearCallingIdentity();
12120 Settings.Global.putInt(
12121 mContext.getContentResolver(),
12122 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12124 synchronized (this) {
12125 mLenientBackgroundCheck = enabled;
12128 Binder.restoreCallingIdentity(ident);
12133 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12134 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12135 "setActivityController()");
12136 synchronized (this) {
12137 mController = controller;
12138 mControllerIsAMonkey = imAMonkey;
12139 Watchdog.getInstance().setActivityController(controller);
12144 public void setUserIsMonkey(boolean userIsMonkey) {
12145 synchronized (this) {
12146 synchronized (mPidsSelfLocked) {
12147 final int callingPid = Binder.getCallingPid();
12148 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12149 if (precessRecord == null) {
12150 throw new SecurityException("Unknown process: " + callingPid);
12152 if (precessRecord.instrumentationUiAutomationConnection == null) {
12153 throw new SecurityException("Only an instrumentation process "
12154 + "with a UiAutomation can call setUserIsMonkey");
12157 mUserIsMonkey = userIsMonkey;
12162 public boolean isUserAMonkey() {
12163 synchronized (this) {
12164 // If there is a controller also implies the user is a monkey.
12165 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12169 public void requestBugReport(int bugreportType) {
12170 String service = null;
12171 switch (bugreportType) {
12172 case ActivityManager.BUGREPORT_OPTION_FULL:
12173 service = "bugreport";
12175 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12176 service = "bugreportplus";
12178 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12179 service = "bugreportremote";
12181 case ActivityManager.BUGREPORT_OPTION_WEAR:
12182 service = "bugreportwear";
12184 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12185 service = "bugreportelefony";
12188 if (service == null) {
12189 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12192 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12193 SystemProperties.set("ctl.start", service);
12196 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12197 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12200 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12201 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12202 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12204 return KEY_DISPATCHING_TIMEOUT;
12208 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12209 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12210 != PackageManager.PERMISSION_GRANTED) {
12211 throw new SecurityException("Requires permission "
12212 + android.Manifest.permission.FILTER_EVENTS);
12214 ProcessRecord proc;
12216 synchronized (this) {
12217 synchronized (mPidsSelfLocked) {
12218 proc = mPidsSelfLocked.get(pid);
12220 timeout = getInputDispatchingTimeoutLocked(proc);
12223 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12231 * Handle input dispatching timeouts.
12232 * Returns whether input dispatching should be aborted or not.
12234 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12235 final ActivityRecord activity, final ActivityRecord parent,
12236 final boolean aboveSystem, String reason) {
12237 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12238 != PackageManager.PERMISSION_GRANTED) {
12239 throw new SecurityException("Requires permission "
12240 + android.Manifest.permission.FILTER_EVENTS);
12243 final String annotation;
12244 if (reason == null) {
12245 annotation = "Input dispatching timed out";
12247 annotation = "Input dispatching timed out (" + reason + ")";
12250 if (proc != null) {
12251 synchronized (this) {
12252 if (proc.debugging) {
12257 // Give more time since we were dexopting.
12258 mDidDexOpt = false;
12262 if (proc.instrumentationClass != null) {
12263 Bundle info = new Bundle();
12264 info.putString("shortMsg", "keyDispatchingTimedOut");
12265 info.putString("longMsg", annotation);
12266 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12270 mHandler.post(new Runnable() {
12272 public void run() {
12273 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12282 public Bundle getAssistContextExtras(int requestType) {
12283 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12284 null, null, true /* focused */, true /* newSessionId */,
12285 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12289 synchronized (pae) {
12290 while (!pae.haveResult) {
12293 } catch (InterruptedException e) {
12297 synchronized (this) {
12298 buildAssistBundleLocked(pae, pae.result);
12299 mPendingAssistExtras.remove(pae);
12300 mUiHandler.removeCallbacks(pae);
12306 public boolean isAssistDataAllowedOnCurrentActivity() {
12308 synchronized (this) {
12309 userId = mUserController.getCurrentUserIdLocked();
12310 ActivityRecord activity = getFocusedStack().topActivity();
12311 if (activity == null) {
12314 userId = activity.userId;
12316 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12317 Context.DEVICE_POLICY_SERVICE);
12318 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12322 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12323 long ident = Binder.clearCallingIdentity();
12325 synchronized (this) {
12326 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12327 ActivityRecord top = getFocusedStack().topActivity();
12328 if (top != caller) {
12329 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12330 + " is not current top " + top);
12333 if (!top.nowVisible) {
12334 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12335 + " is not visible");
12339 AssistUtils utils = new AssistUtils(mContext);
12340 return utils.showSessionForActiveService(args,
12341 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12343 Binder.restoreCallingIdentity(ident);
12348 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12349 Bundle receiverExtras,
12350 IBinder activityToken, boolean focused, boolean newSessionId) {
12351 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12352 activityToken, focused, newSessionId,
12353 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12357 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12358 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12359 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12360 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12361 "enqueueAssistContext()");
12362 synchronized (this) {
12363 ActivityRecord activity = getFocusedStack().topActivity();
12364 if (activity == null) {
12365 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12368 if (activity.app == null || activity.app.thread == null) {
12369 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12373 if (activityToken != null) {
12374 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12375 if (activity != caller) {
12376 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12377 + " is not current top " + activity);
12382 activity = ActivityRecord.forTokenLocked(activityToken);
12383 if (activity == null) {
12384 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12385 + " couldn't be found");
12390 PendingAssistExtras pae;
12391 Bundle extras = new Bundle();
12392 if (args != null) {
12393 extras.putAll(args);
12395 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12396 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12397 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12399 // Increment the sessionId if necessary
12400 if (newSessionId) {
12404 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12405 requestType, mViSessionId);
12406 mPendingAssistExtras.add(pae);
12407 mUiHandler.postDelayed(pae, timeout);
12408 } catch (RemoteException e) {
12409 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12416 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12417 IResultReceiver receiver;
12418 synchronized (this) {
12419 mPendingAssistExtras.remove(pae);
12420 receiver = pae.receiver;
12422 if (receiver != null) {
12423 // Caller wants result sent back to them.
12424 Bundle sendBundle = new Bundle();
12425 // At least return the receiver extras
12426 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12427 pae.receiverExtras);
12429 pae.receiver.send(0, sendBundle);
12430 } catch (RemoteException e) {
12435 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12436 if (result != null) {
12437 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12439 if (pae.hint != null) {
12440 pae.extras.putBoolean(pae.hint, true);
12444 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12445 AssistContent content, Uri referrer) {
12446 PendingAssistExtras pae = (PendingAssistExtras)token;
12447 synchronized (pae) {
12448 pae.result = extras;
12449 pae.structure = structure;
12450 pae.content = content;
12451 if (referrer != null) {
12452 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12454 pae.haveResult = true;
12456 if (pae.intent == null && pae.receiver == null) {
12457 // Caller is just waiting for the result.
12462 // We are now ready to launch the assist activity.
12463 IResultReceiver sendReceiver = null;
12464 Bundle sendBundle = null;
12465 synchronized (this) {
12466 buildAssistBundleLocked(pae, extras);
12467 boolean exists = mPendingAssistExtras.remove(pae);
12468 mUiHandler.removeCallbacks(pae);
12473 if ((sendReceiver=pae.receiver) != null) {
12474 // Caller wants result sent back to them.
12475 sendBundle = new Bundle();
12476 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12477 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12478 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12479 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12480 pae.receiverExtras);
12483 if (sendReceiver != null) {
12485 sendReceiver.send(0, sendBundle);
12486 } catch (RemoteException e) {
12491 long ident = Binder.clearCallingIdentity();
12493 pae.intent.replaceExtras(pae.extras);
12494 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12495 | Intent.FLAG_ACTIVITY_SINGLE_TOP
12496 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12497 closeSystemDialogs("assist");
12499 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12500 } catch (ActivityNotFoundException e) {
12501 Slog.w(TAG, "No activity to handle assist action.", e);
12504 Binder.restoreCallingIdentity(ident);
12508 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12510 return enqueueAssistContext(requestType, intent, hint, null, null, null,
12511 true /* focused */, true /* newSessionId */,
12512 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12515 public void registerProcessObserver(IProcessObserver observer) {
12516 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12517 "registerProcessObserver()");
12518 synchronized (this) {
12519 mProcessObservers.register(observer);
12524 public void unregisterProcessObserver(IProcessObserver observer) {
12525 synchronized (this) {
12526 mProcessObservers.unregister(observer);
12531 public void registerUidObserver(IUidObserver observer, int which) {
12532 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12533 "registerUidObserver()");
12534 synchronized (this) {
12535 mUidObservers.register(observer, which);
12540 public void unregisterUidObserver(IUidObserver observer) {
12541 synchronized (this) {
12542 mUidObservers.unregister(observer);
12547 public boolean convertFromTranslucent(IBinder token) {
12548 final long origId = Binder.clearCallingIdentity();
12550 synchronized (this) {
12551 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12555 final boolean translucentChanged = r.changeWindowTranslucency(true);
12556 if (translucentChanged) {
12557 r.task.stack.releaseBackgroundResources(r);
12558 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12560 mWindowManager.setAppFullscreen(token, true);
12561 return translucentChanged;
12564 Binder.restoreCallingIdentity(origId);
12569 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12570 final long origId = Binder.clearCallingIdentity();
12572 synchronized (this) {
12573 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12577 int index = r.task.mActivities.lastIndexOf(r);
12579 ActivityRecord under = r.task.mActivities.get(index - 1);
12580 under.returningOptions = options;
12582 final boolean translucentChanged = r.changeWindowTranslucency(false);
12583 if (translucentChanged) {
12584 r.task.stack.convertActivityToTranslucent(r);
12586 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12587 mWindowManager.setAppFullscreen(token, false);
12588 return translucentChanged;
12591 Binder.restoreCallingIdentity(origId);
12596 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12597 final long origId = Binder.clearCallingIdentity();
12599 synchronized (this) {
12600 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12602 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12607 Binder.restoreCallingIdentity(origId);
12612 public boolean isBackgroundVisibleBehind(IBinder token) {
12613 final long origId = Binder.clearCallingIdentity();
12615 synchronized (this) {
12616 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12617 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12618 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12619 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12623 Binder.restoreCallingIdentity(origId);
12628 public ActivityOptions getActivityOptions(IBinder token) {
12629 final long origId = Binder.clearCallingIdentity();
12631 synchronized (this) {
12632 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12634 final ActivityOptions activityOptions = r.pendingOptions;
12635 r.pendingOptions = null;
12636 return activityOptions;
12641 Binder.restoreCallingIdentity(origId);
12646 public void setImmersive(IBinder token, boolean immersive) {
12647 synchronized(this) {
12648 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12650 throw new IllegalArgumentException();
12652 r.immersive = immersive;
12654 // update associated state if we're frontmost
12655 if (r == mFocusedActivity) {
12656 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12657 applyUpdateLockStateLocked(r);
12663 public boolean isImmersive(IBinder token) {
12664 synchronized (this) {
12665 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12667 throw new IllegalArgumentException();
12669 return r.immersive;
12673 public void setVrThread(int tid) {
12674 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12675 throw new UnsupportedOperationException("VR mode not supported on this device!");
12678 synchronized (this) {
12679 ProcessRecord proc;
12680 synchronized (mPidsSelfLocked) {
12681 final int pid = Binder.getCallingPid();
12682 proc = mPidsSelfLocked.get(pid);
12684 if (proc != null && mInVrMode && tid >= 0) {
12685 // ensure the tid belongs to the process
12686 if (!Process.isThreadInProcess(pid, tid)) {
12687 throw new IllegalArgumentException("VR thread does not belong to process");
12690 // reset existing VR thread to CFS if this thread still exists and belongs to
12691 // the calling process
12692 if (proc.vrThreadTid != 0
12693 && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12695 Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12696 } catch (IllegalArgumentException e) {
12697 // Ignore this. Only occurs in race condition where previous VR thread
12698 // was destroyed during this method call.
12702 proc.vrThreadTid = tid;
12704 // promote to FIFO now if the tid is non-zero
12706 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12707 proc.vrThreadTid > 0) {
12708 Process.setThreadScheduler(proc.vrThreadTid,
12709 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12711 } catch (IllegalArgumentException e) {
12712 Slog.e(TAG, "Failed to set scheduling policy, thread does"
12713 + " not exist:\n" + e);
12721 public void setRenderThread(int tid) {
12722 synchronized (this) {
12723 ProcessRecord proc;
12724 synchronized (mPidsSelfLocked) {
12725 int pid = Binder.getCallingPid();
12726 proc = mPidsSelfLocked.get(pid);
12727 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12728 // ensure the tid belongs to the process
12729 if (!Process.isThreadInProcess(pid, tid)) {
12730 throw new IllegalArgumentException(
12731 "Render thread does not belong to process");
12733 proc.renderThreadTid = tid;
12734 if (DEBUG_OOM_ADJ) {
12735 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12737 // promote to FIFO now
12738 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12739 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12740 if (mUseFifoUiScheduling) {
12741 Process.setThreadScheduler(proc.renderThreadTid,
12742 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12744 Process.setThreadPriority(proc.renderThreadTid, -10);
12748 if (DEBUG_OOM_ADJ) {
12749 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12750 "PID: " + pid + ", TID: " + tid + " FIFO: " +
12751 mUseFifoUiScheduling);
12759 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12760 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12761 throw new UnsupportedOperationException("VR mode not supported on this device!");
12764 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12767 synchronized (this) {
12768 r = ActivityRecord.isInStackLocked(token);
12772 throw new IllegalArgumentException();
12776 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12777 VrManagerInternal.NO_ERROR) {
12781 synchronized(this) {
12782 r.requestedVrComponent = (enabled) ? packageName : null;
12784 // Update associated state if this activity is currently focused
12785 if (r == mFocusedActivity) {
12786 applyUpdateVrModeLocked(r);
12793 public boolean isVrModePackageEnabled(ComponentName packageName) {
12794 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12795 throw new UnsupportedOperationException("VR mode not supported on this device!");
12798 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12800 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12801 VrManagerInternal.NO_ERROR;
12804 public boolean isTopActivityImmersive() {
12805 enforceNotIsolatedCaller("startActivity");
12806 synchronized (this) {
12807 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12808 return (r != null) ? r.immersive : false;
12813 public boolean isTopOfTask(IBinder token) {
12814 synchronized (this) {
12815 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12817 throw new IllegalArgumentException();
12819 return r.task.getTopActivity() == r;
12824 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12825 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12826 String msg = "Permission Denial: setHasTopUi() from pid="
12827 + Binder.getCallingPid()
12828 + ", uid=" + Binder.getCallingUid()
12829 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12831 throw new SecurityException(msg);
12833 final int pid = Binder.getCallingPid();
12834 final long origId = Binder.clearCallingIdentity();
12836 synchronized (this) {
12837 boolean changed = false;
12839 synchronized (mPidsSelfLocked) {
12840 pr = mPidsSelfLocked.get(pid);
12842 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12845 if (pr.hasTopUi != hasTopUi) {
12846 Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12847 pr.hasTopUi = hasTopUi;
12852 updateOomAdjLocked(pr);
12856 Binder.restoreCallingIdentity(origId);
12860 public final void enterSafeMode() {
12861 synchronized(this) {
12862 // It only makes sense to do this before the system is ready
12863 // and started launching other packages.
12864 if (!mSystemReady) {
12866 AppGlobals.getPackageManager().enterSafeMode();
12867 } catch (RemoteException e) {
12875 public final void showSafeModeOverlay() {
12876 View v = LayoutInflater.from(mContext).inflate(
12877 com.android.internal.R.layout.safe_mode, null);
12878 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12879 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12880 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12881 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12882 lp.gravity = Gravity.BOTTOM | Gravity.START;
12883 lp.format = v.getBackground().getOpacity();
12884 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12885 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12886 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12887 ((WindowManager)mContext.getSystemService(
12888 Context.WINDOW_SERVICE)).addView(v, lp);
12891 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12892 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12895 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12896 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12897 synchronized (stats) {
12898 if (mBatteryStatsService.isOnBattery()) {
12899 mBatteryStatsService.enforceCallingPermission();
12900 int MY_UID = Binder.getCallingUid();
12902 if (sender == null) {
12905 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12907 BatteryStatsImpl.Uid.Pkg pkg =
12908 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12909 sourcePkg != null ? sourcePkg : rec.key.packageName);
12910 pkg.noteWakeupAlarmLocked(tag);
12915 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12916 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12919 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12920 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12921 synchronized (stats) {
12922 mBatteryStatsService.enforceCallingPermission();
12923 int MY_UID = Binder.getCallingUid();
12925 if (sender == null) {
12928 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12930 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12934 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12935 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12938 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12939 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12940 synchronized (stats) {
12941 mBatteryStatsService.enforceCallingPermission();
12942 int MY_UID = Binder.getCallingUid();
12944 if (sender == null) {
12947 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12949 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12953 public boolean killPids(int[] pids, String pReason, boolean secure) {
12954 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12955 throw new SecurityException("killPids only available to the system");
12957 String reason = (pReason == null) ? "Unknown" : pReason;
12958 // XXX Note: don't acquire main activity lock here, because the window
12959 // manager calls in with its locks held.
12961 boolean killed = false;
12962 synchronized (mPidsSelfLocked) {
12964 for (int i=0; i<pids.length; i++) {
12965 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12966 if (proc != null) {
12967 int type = proc.setAdj;
12968 if (type > worstType) {
12974 // If the worst oom_adj is somewhere in the cached proc LRU range,
12975 // then constrain it so we will kill all cached procs.
12976 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12977 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12978 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12981 // If this is not a secure call, don't let it kill processes that
12983 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12984 worstType = ProcessList.SERVICE_ADJ;
12987 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12988 for (int i=0; i<pids.length; i++) {
12989 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12990 if (proc == null) {
12993 int adj = proc.setAdj;
12994 if (adj >= worstType && !proc.killedByAm) {
12995 proc.kill(reason, true);
13004 public void killUid(int appId, int userId, String reason) {
13005 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13006 synchronized (this) {
13007 final long identity = Binder.clearCallingIdentity();
13009 killPackageProcessesLocked(null, appId, userId,
13010 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13011 reason != null ? reason : "kill uid");
13013 Binder.restoreCallingIdentity(identity);
13019 public boolean killProcessesBelowForeground(String reason) {
13020 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13021 throw new SecurityException("killProcessesBelowForeground() only available to system");
13024 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13027 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13028 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13029 throw new SecurityException("killProcessesBelowAdj() only available to system");
13032 boolean killed = false;
13033 synchronized (mPidsSelfLocked) {
13034 final int size = mPidsSelfLocked.size();
13035 for (int i = 0; i < size; i++) {
13036 final int pid = mPidsSelfLocked.keyAt(i);
13037 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13038 if (proc == null) continue;
13040 final int adj = proc.setAdj;
13041 if (adj > belowAdj && !proc.killedByAm) {
13042 proc.kill(reason, true);
13051 public void hang(final IBinder who, boolean allowRestart) {
13052 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13053 != PackageManager.PERMISSION_GRANTED) {
13054 throw new SecurityException("Requires permission "
13055 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13058 final IBinder.DeathRecipient death = new DeathRecipient() {
13060 public void binderDied() {
13061 synchronized (this) {
13068 who.linkToDeath(death, 0);
13069 } catch (RemoteException e) {
13070 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13074 synchronized (this) {
13075 Watchdog.getInstance().setAllowRestart(allowRestart);
13076 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13077 synchronized (death) {
13078 while (who.isBinderAlive()) {
13081 } catch (InterruptedException e) {
13085 Watchdog.getInstance().setAllowRestart(true);
13090 public void restart() {
13091 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13092 != PackageManager.PERMISSION_GRANTED) {
13093 throw new SecurityException("Requires permission "
13094 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13097 Log.i(TAG, "Sending shutdown broadcast...");
13099 BroadcastReceiver br = new BroadcastReceiver() {
13100 @Override public void onReceive(Context context, Intent intent) {
13101 // Now the broadcast is done, finish up the low-level shutdown.
13102 Log.i(TAG, "Shutting down activity manager...");
13104 Log.i(TAG, "Shutdown complete, restarting!");
13105 Process.killProcess(Process.myPid());
13110 // First send the high-level shut down broadcast.
13111 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13112 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13113 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13114 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13115 mContext.sendOrderedBroadcastAsUser(intent,
13116 UserHandle.ALL, null, br, mHandler, 0, null, null);
13118 br.onReceive(mContext, intent);
13121 private long getLowRamTimeSinceIdle(long now) {
13122 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13126 public void performIdleMaintenance() {
13127 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13128 != PackageManager.PERMISSION_GRANTED) {
13129 throw new SecurityException("Requires permission "
13130 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13133 synchronized (this) {
13134 final long now = SystemClock.uptimeMillis();
13135 final long timeSinceLastIdle = now - mLastIdleTime;
13136 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13137 mLastIdleTime = now;
13138 mLowRamTimeSinceLastIdle = 0;
13139 if (mLowRamStartTime != 0) {
13140 mLowRamStartTime = now;
13143 StringBuilder sb = new StringBuilder(128);
13144 sb.append("Idle maintenance over ");
13145 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13146 sb.append(" low RAM for ");
13147 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13148 Slog.i(TAG, sb.toString());
13150 // If at least 1/3 of our time since the last idle period has been spent
13151 // with RAM low, then we want to kill processes.
13152 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13154 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13155 ProcessRecord proc = mLruProcesses.get(i);
13156 if (proc.notCachedSinceIdle) {
13157 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13158 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13159 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13160 if (doKilling && proc.initialIdlePss != 0
13161 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13162 sb = new StringBuilder(128);
13164 sb.append(proc.processName);
13165 sb.append(" in idle maint: pss=");
13166 sb.append(proc.lastPss);
13167 sb.append(", swapPss=");
13168 sb.append(proc.lastSwapPss);
13169 sb.append(", initialPss=");
13170 sb.append(proc.initialIdlePss);
13171 sb.append(", period=");
13172 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13173 sb.append(", lowRamPeriod=");
13174 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13175 Slog.wtfQuiet(TAG, sb.toString());
13176 proc.kill("idle maint (pss " + proc.lastPss
13177 + " from " + proc.initialIdlePss + ")", true);
13180 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13181 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13182 proc.notCachedSinceIdle = true;
13183 proc.initialIdlePss = 0;
13184 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13185 mTestPssMode, isSleepingLocked(), now);
13189 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13190 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13195 public void sendIdleJobTrigger() {
13196 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13197 != PackageManager.PERMISSION_GRANTED) {
13198 throw new SecurityException("Requires permission "
13199 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13202 final long ident = Binder.clearCallingIdentity();
13204 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13205 .setPackage("android")
13206 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13207 broadcastIntent(null, intent, null, null, 0, null, null, null,
13208 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13210 Binder.restoreCallingIdentity(ident);
13214 private void retrieveSettings() {
13215 final ContentResolver resolver = mContext.getContentResolver();
13216 final boolean freeformWindowManagement =
13217 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13218 || Settings.Global.getInt(
13219 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13220 final boolean supportsPictureInPicture =
13221 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13223 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13224 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13225 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13226 final boolean alwaysFinishActivities =
13227 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13228 final boolean lenientBackgroundCheck =
13229 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13230 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13231 final boolean forceResizable = Settings.Global.getInt(
13232 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13233 final boolean supportsLeanbackOnly =
13234 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13236 // Transfer any global setting for forcing RTL layout, into a System Property
13237 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13239 final Configuration configuration = new Configuration();
13240 Settings.System.getConfiguration(resolver, configuration);
13242 // This will take care of setting the correct layout direction flags
13243 configuration.setLayoutDirection(configuration.locale);
13246 synchronized (this) {
13247 mDebugApp = mOrigDebugApp = debugApp;
13248 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13249 mAlwaysFinishActivities = alwaysFinishActivities;
13250 mLenientBackgroundCheck = lenientBackgroundCheck;
13251 mSupportsLeanbackOnly = supportsLeanbackOnly;
13252 mForceResizableActivities = forceResizable;
13253 mWindowManager.setForceResizableTasks(mForceResizableActivities);
13254 if (supportsMultiWindow || forceResizable) {
13255 mSupportsMultiWindow = true;
13256 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13257 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13259 mSupportsMultiWindow = false;
13260 mSupportsFreeformWindowManagement = false;
13261 mSupportsPictureInPicture = false;
13263 // This happens before any activities are started, so we can
13264 // change mConfiguration in-place.
13265 updateConfigurationLocked(configuration, null, true);
13266 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13267 "Initial config: " + mConfiguration);
13269 // Load resources only after the current configuration has been set.
13270 final Resources res = mContext.getResources();
13271 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13272 mThumbnailWidth = res.getDimensionPixelSize(
13273 com.android.internal.R.dimen.thumbnail_width);
13274 mThumbnailHeight = res.getDimensionPixelSize(
13275 com.android.internal.R.dimen.thumbnail_height);
13276 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13277 com.android.internal.R.string.config_defaultPictureInPictureBounds));
13278 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13279 com.android.internal.R.string.config_appsNotReportingCrashes));
13280 if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13281 mFullscreenThumbnailScale = (float) res
13282 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13283 (float) mConfiguration.screenWidthDp;
13285 mFullscreenThumbnailScale = res.getFraction(
13286 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13291 public boolean testIsSystemReady() {
13292 // no need to synchronize(this) just to read & return the value
13293 return mSystemReady;
13296 public void systemReady(final Runnable goingCallback) {
13297 synchronized(this) {
13298 if (mSystemReady) {
13299 // If we're done calling all the receivers, run the next "boot phase" passed in
13300 // by the SystemServer
13301 if (goingCallback != null) {
13302 goingCallback.run();
13307 mLocalDeviceIdleController
13308 = LocalServices.getService(DeviceIdleController.LocalService.class);
13310 // Make sure we have the current profile info, since it is needed for security checks.
13311 mUserController.onSystemReady();
13312 mRecentTasks.onSystemReadyLocked();
13313 mAppOpsService.systemReady();
13314 mSystemReady = true;
13317 ArrayList<ProcessRecord> procsToKill = null;
13318 synchronized(mPidsSelfLocked) {
13319 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13320 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13321 if (!isAllowedWhileBooting(proc.info)){
13322 if (procsToKill == null) {
13323 procsToKill = new ArrayList<ProcessRecord>();
13325 procsToKill.add(proc);
13330 synchronized(this) {
13331 if (procsToKill != null) {
13332 for (int i=procsToKill.size()-1; i>=0; i--) {
13333 ProcessRecord proc = procsToKill.get(i);
13334 Slog.i(TAG, "Removing system update proc: " + proc);
13335 removeProcessLocked(proc, true, false, "system update done");
13339 // Now that we have cleaned up any update processes, we
13340 // are ready to start launching real processes and know that
13341 // we won't trample on them any more.
13342 mProcessesReady = true;
13345 Slog.i(TAG, "System now ready");
13346 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13347 SystemClock.uptimeMillis());
13349 synchronized(this) {
13350 // Make sure we have no pre-ready processes sitting around.
13352 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13353 ResolveInfo ri = mContext.getPackageManager()
13354 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13356 CharSequence errorMsg = null;
13358 ActivityInfo ai = ri.activityInfo;
13359 ApplicationInfo app = ai.applicationInfo;
13360 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13361 mTopAction = Intent.ACTION_FACTORY_TEST;
13363 mTopComponent = new ComponentName(app.packageName,
13366 errorMsg = mContext.getResources().getText(
13367 com.android.internal.R.string.factorytest_not_system);
13370 errorMsg = mContext.getResources().getText(
13371 com.android.internal.R.string.factorytest_no_action);
13373 if (errorMsg != null) {
13376 mTopComponent = null;
13377 Message msg = Message.obtain();
13378 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13379 msg.getData().putCharSequence("msg", errorMsg);
13380 mUiHandler.sendMessage(msg);
13385 retrieveSettings();
13386 final int currentUserId;
13387 synchronized (this) {
13388 currentUserId = mUserController.getCurrentUserIdLocked();
13389 readGrantedUriPermissionsLocked();
13392 if (goingCallback != null) goingCallback.run();
13394 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13395 Integer.toString(currentUserId), currentUserId);
13396 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13397 Integer.toString(currentUserId), currentUserId);
13398 mSystemServiceManager.startUser(currentUserId);
13400 synchronized (this) {
13401 // Only start up encryption-aware persistent apps; once user is
13402 // unlocked we'll come back around and start unaware apps
13403 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13405 // Start up initial activity.
13407 // Enable home activity for system user, so that the system can always boot
13408 if (UserManager.isSplitSystemUser()) {
13409 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13411 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13412 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13413 UserHandle.USER_SYSTEM);
13414 } catch (RemoteException e) {
13415 throw e.rethrowAsRuntimeException();
13418 startHomeActivityLocked(currentUserId, "systemReady");
13421 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13422 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13423 + " data partition or your device will be unstable.");
13424 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13426 } catch (RemoteException e) {
13429 if (!Build.isBuildConsistent()) {
13430 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13431 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13434 long ident = Binder.clearCallingIdentity();
13436 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13438 | Intent.FLAG_RECEIVER_FOREGROUND);
13439 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13440 broadcastIntentLocked(null, null, intent,
13441 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13442 null, false, false, MY_PID, Process.SYSTEM_UID,
13444 intent = new Intent(Intent.ACTION_USER_STARTING);
13445 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13446 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13447 broadcastIntentLocked(null, null, intent,
13448 null, new IIntentReceiver.Stub() {
13450 public void performReceive(Intent intent, int resultCode, String data,
13451 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13452 throws RemoteException {
13455 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13456 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13457 } catch (Throwable t) {
13458 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13460 Binder.restoreCallingIdentity(ident);
13462 mStackSupervisor.resumeFocusedStackTopActivityLocked();
13463 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13467 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13468 synchronized (this) {
13469 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13473 void skipCurrentReceiverLocked(ProcessRecord app) {
13474 for (BroadcastQueue queue : mBroadcastQueues) {
13475 queue.skipCurrentReceiverLocked(app);
13480 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13481 * The application process will exit immediately after this call returns.
13482 * @param app object of the crashing app, null for the system server
13483 * @param crashInfo describing the exception
13485 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13486 ProcessRecord r = findAppProcess(app, "Crash");
13487 final String processName = app == null ? "system_server"
13488 : (r == null ? "unknown" : r.processName);
13490 handleApplicationCrashInner("crash", r, processName, crashInfo);
13493 /* Native crash reporting uses this inner version because it needs to be somewhat
13494 * decoupled from the AM-managed cleanup lifecycle
13496 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13497 ApplicationErrorReport.CrashInfo crashInfo) {
13498 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13499 UserHandle.getUserId(Binder.getCallingUid()), processName,
13500 r == null ? -1 : r.info.flags,
13501 crashInfo.exceptionClassName,
13502 crashInfo.exceptionMessage,
13503 crashInfo.throwFileName,
13504 crashInfo.throwLineNumber);
13506 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13508 mAppErrors.crashApplication(r, crashInfo);
13511 public void handleApplicationStrictModeViolation(
13514 StrictMode.ViolationInfo info) {
13515 ProcessRecord r = findAppProcess(app, "StrictMode");
13520 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13521 Integer stackFingerprint = info.hashCode();
13522 boolean logIt = true;
13523 synchronized (mAlreadyLoggedViolatedStacks) {
13524 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13526 // TODO: sub-sample into EventLog for these, with
13527 // the info.durationMillis? Then we'd get
13528 // the relative pain numbers, without logging all
13529 // the stack traces repeatedly. We'd want to do
13530 // likewise in the client code, which also does
13531 // dup suppression, before the Binder call.
13533 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13534 mAlreadyLoggedViolatedStacks.clear();
13536 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13540 logStrictModeViolationToDropBox(r, info);
13544 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13545 AppErrorResult result = new AppErrorResult();
13546 synchronized (this) {
13547 final long origId = Binder.clearCallingIdentity();
13549 Message msg = Message.obtain();
13550 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13551 HashMap<String, Object> data = new HashMap<String, Object>();
13552 data.put("result", result);
13553 data.put("app", r);
13554 data.put("violationMask", violationMask);
13555 data.put("info", info);
13557 mUiHandler.sendMessage(msg);
13559 Binder.restoreCallingIdentity(origId);
13561 int res = result.get();
13562 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13566 // Depending on the policy in effect, there could be a bunch of
13567 // these in quick succession so we try to batch these together to
13568 // minimize disk writes, number of dropbox entries, and maximize
13569 // compression, by having more fewer, larger records.
13570 private void logStrictModeViolationToDropBox(
13571 ProcessRecord process,
13572 StrictMode.ViolationInfo info) {
13573 if (info == null) {
13576 final boolean isSystemApp = process == null ||
13577 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13578 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13579 final String processName = process == null ? "unknown" : process.processName;
13580 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13581 final DropBoxManager dbox = (DropBoxManager)
13582 mContext.getSystemService(Context.DROPBOX_SERVICE);
13584 // Exit early if the dropbox isn't configured to accept this report type.
13585 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13587 boolean bufferWasEmpty;
13588 boolean needsFlush;
13589 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13590 synchronized (sb) {
13591 bufferWasEmpty = sb.length() == 0;
13592 appendDropBoxProcessHeaders(process, processName, sb);
13593 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13594 sb.append("System-App: ").append(isSystemApp).append("\n");
13595 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13596 if (info.violationNumThisLoop != 0) {
13597 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13599 if (info.numAnimationsRunning != 0) {
13600 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13602 if (info.broadcastIntentAction != null) {
13603 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13605 if (info.durationMillis != -1) {
13606 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13608 if (info.numInstances != -1) {
13609 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13611 if (info.tags != null) {
13612 for (String tag : info.tags) {
13613 sb.append("Span-Tag: ").append(tag).append("\n");
13617 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13618 sb.append(info.crashInfo.stackTrace);
13621 if (info.message != null) {
13622 sb.append(info.message);
13626 // Only buffer up to ~64k. Various logging bits truncate
13628 needsFlush = (sb.length() > 64 * 1024);
13631 // Flush immediately if the buffer's grown too large, or this
13632 // is a non-system app. Non-system apps are isolated with a
13633 // different tag & policy and not batched.
13635 // Batching is useful during internal testing with
13636 // StrictMode settings turned up high. Without batching,
13637 // thousands of separate files could be created on boot.
13638 if (!isSystemApp || needsFlush) {
13639 new Thread("Error dump: " + dropboxTag) {
13641 public void run() {
13643 synchronized (sb) {
13644 report = sb.toString();
13645 sb.delete(0, sb.length());
13648 if (report.length() != 0) {
13649 dbox.addText(dropboxTag, report);
13656 // System app batching:
13657 if (!bufferWasEmpty) {
13658 // An existing dropbox-writing thread is outstanding, so
13659 // we don't need to start it up. The existing thread will
13660 // catch the buffer appends we just did.
13664 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13665 // (After this point, we shouldn't access AMS internal data structures.)
13666 new Thread("Error dump: " + dropboxTag) {
13668 public void run() {
13669 // 5 second sleep to let stacks arrive and be batched together
13671 Thread.sleep(5000); // 5 seconds
13672 } catch (InterruptedException e) {}
13674 String errorReport;
13675 synchronized (mStrictModeBuffer) {
13676 errorReport = mStrictModeBuffer.toString();
13677 if (errorReport.length() == 0) {
13680 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13681 mStrictModeBuffer.trimToSize();
13683 dbox.addText(dropboxTag, errorReport);
13689 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13690 * @param app object of the crashing app, null for the system server
13691 * @param tag reported by the caller
13692 * @param system whether this wtf is coming from the system
13693 * @param crashInfo describing the context of the error
13694 * @return true if the process should exit immediately (WTF is fatal)
13696 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13697 final ApplicationErrorReport.CrashInfo crashInfo) {
13698 final int callingUid = Binder.getCallingUid();
13699 final int callingPid = Binder.getCallingPid();
13702 // If this is coming from the system, we could very well have low-level
13703 // system locks held, so we want to do this all asynchronously. And we
13704 // never want this to become fatal, so there is that too.
13705 mHandler.post(new Runnable() {
13706 @Override public void run() {
13707 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13713 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13716 if (r != null && r.pid != Process.myPid() &&
13717 Settings.Global.getInt(mContext.getContentResolver(),
13718 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13719 mAppErrors.crashApplication(r, crashInfo);
13726 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13727 final ApplicationErrorReport.CrashInfo crashInfo) {
13728 final ProcessRecord r = findAppProcess(app, "WTF");
13729 final String processName = app == null ? "system_server"
13730 : (r == null ? "unknown" : r.processName);
13732 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13733 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13735 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13741 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13742 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13744 private ProcessRecord findAppProcess(IBinder app, String reason) {
13749 synchronized (this) {
13750 final int NP = mProcessNames.getMap().size();
13751 for (int ip=0; ip<NP; ip++) {
13752 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13753 final int NA = apps.size();
13754 for (int ia=0; ia<NA; ia++) {
13755 ProcessRecord p = apps.valueAt(ia);
13756 if (p.thread != null && p.thread.asBinder() == app) {
13762 Slog.w(TAG, "Can't find mystery application for " + reason
13763 + " from pid=" + Binder.getCallingPid()
13764 + " uid=" + Binder.getCallingUid() + ": " + app);
13770 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13771 * to append various headers to the dropbox log text.
13773 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13774 StringBuilder sb) {
13775 // Watchdog thread ends up invoking this function (with
13776 // a null ProcessRecord) to add the stack file to dropbox.
13777 // Do not acquire a lock on this (am) in such cases, as it
13778 // could cause a potential deadlock, if and when watchdog
13779 // is invoked due to unavailability of lock on am and it
13780 // would prevent watchdog from killing system_server.
13781 if (process == null) {
13782 sb.append("Process: ").append(processName).append("\n");
13785 // Note: ProcessRecord 'process' is guarded by the service
13786 // instance. (notably process.pkgList, which could otherwise change
13787 // concurrently during execution of this method)
13788 synchronized (this) {
13789 sb.append("Process: ").append(processName).append("\n");
13790 int flags = process.info.flags;
13791 IPackageManager pm = AppGlobals.getPackageManager();
13792 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13793 for (int ip=0; ip<process.pkgList.size(); ip++) {
13794 String pkg = process.pkgList.keyAt(ip);
13795 sb.append("Package: ").append(pkg);
13797 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13799 sb.append(" v").append(pi.versionCode);
13800 if (pi.versionName != null) {
13801 sb.append(" (").append(pi.versionName).append(")");
13804 } catch (RemoteException e) {
13805 Slog.e(TAG, "Error getting package info: " + pkg, e);
13812 private static String processClass(ProcessRecord process) {
13813 if (process == null || process.pid == MY_PID) {
13814 return "system_server";
13815 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13816 return "system_app";
13822 private volatile long mWtfClusterStart;
13823 private volatile int mWtfClusterCount;
13826 * Write a description of an error (crash, WTF, ANR) to the drop box.
13827 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13828 * @param process which caused the error, null means the system server
13829 * @param activity which triggered the error, null if unknown
13830 * @param parent activity related to the error, null if unknown
13831 * @param subject line related to the error, null if absent
13832 * @param report in long form describing the error, null if absent
13833 * @param dataFile text file to include in the report, null if none
13834 * @param crashInfo giving an application stack trace, null if absent
13836 public void addErrorToDropBox(String eventType,
13837 ProcessRecord process, String processName, ActivityRecord activity,
13838 ActivityRecord parent, String subject,
13839 final String report, final File dataFile,
13840 final ApplicationErrorReport.CrashInfo crashInfo) {
13841 // NOTE -- this must never acquire the ActivityManagerService lock,
13842 // otherwise the watchdog may be prevented from resetting the system.
13844 final String dropboxTag = processClass(process) + "_" + eventType;
13845 final DropBoxManager dbox = (DropBoxManager)
13846 mContext.getSystemService(Context.DROPBOX_SERVICE);
13848 // Exit early if the dropbox isn't configured to accept this report type.
13849 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13851 // Rate-limit how often we're willing to do the heavy lifting below to
13852 // collect and record logs; currently 5 logs per 10 second period.
13853 final long now = SystemClock.elapsedRealtime();
13854 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13855 mWtfClusterStart = now;
13856 mWtfClusterCount = 1;
13858 if (mWtfClusterCount++ >= 5) return;
13861 final StringBuilder sb = new StringBuilder(1024);
13862 appendDropBoxProcessHeaders(process, processName, sb);
13863 if (process != null) {
13864 sb.append("Foreground: ")
13865 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13868 if (activity != null) {
13869 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13871 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13872 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13874 if (parent != null && parent != activity) {
13875 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13877 if (subject != null) {
13878 sb.append("Subject: ").append(subject).append("\n");
13880 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13881 if (Debug.isDebuggerConnected()) {
13882 sb.append("Debugger: Connected\n");
13886 // Do the rest in a worker thread to avoid blocking the caller on I/O
13887 // (After this point, we shouldn't access AMS internal data structures.)
13888 Thread worker = new Thread("Error dump: " + dropboxTag) {
13890 public void run() {
13891 if (report != null) {
13895 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13896 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13897 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13898 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13900 if (dataFile != null && maxDataFileSize > 0) {
13902 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13903 "\n\n[[TRUNCATED]]"));
13904 } catch (IOException e) {
13905 Slog.e(TAG, "Error reading " + dataFile, e);
13908 if (crashInfo != null && crashInfo.stackTrace != null) {
13909 sb.append(crashInfo.stackTrace);
13915 // Merge several logcat streams, and take the last N lines
13916 InputStreamReader input = null;
13918 java.lang.Process logcat = new ProcessBuilder(
13919 "/system/bin/timeout", "-k", "15s", "10s",
13920 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13921 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13922 .redirectErrorStream(true).start();
13924 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13925 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13926 input = new InputStreamReader(logcat.getInputStream());
13929 char[] buf = new char[8192];
13930 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13931 } catch (IOException e) {
13932 Slog.e(TAG, "Error running logcat", e);
13934 if (input != null) try { input.close(); } catch (IOException e) {}
13938 dbox.addText(dropboxTag, sb.toString());
13942 if (process == null) {
13943 // If process is null, we are being called from some internal code
13944 // and may be about to die -- run this synchronously.
13952 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13953 enforceNotIsolatedCaller("getProcessesInErrorState");
13954 // assume our apps are happy - lazy create the list
13955 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13957 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13958 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13959 int userId = UserHandle.getUserId(Binder.getCallingUid());
13961 synchronized (this) {
13963 // iterate across all processes
13964 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13965 ProcessRecord app = mLruProcesses.get(i);
13966 if (!allUsers && app.userId != userId) {
13969 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13970 // This one's in trouble, so we'll generate a report for it
13971 // crashes are higher priority (in case there's a crash *and* an anr)
13972 ActivityManager.ProcessErrorStateInfo report = null;
13973 if (app.crashing) {
13974 report = app.crashingReport;
13975 } else if (app.notResponding) {
13976 report = app.notRespondingReport;
13979 if (report != null) {
13980 if (errList == null) {
13981 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13983 errList.add(report);
13985 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13986 " crashing = " + app.crashing +
13987 " notResponding = " + app.notResponding);
13996 static int procStateToImportance(int procState, int memAdj,
13997 ActivityManager.RunningAppProcessInfo currApp) {
13998 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13999 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14000 currApp.lru = memAdj;
14007 private void fillInProcMemInfo(ProcessRecord app,
14008 ActivityManager.RunningAppProcessInfo outInfo) {
14009 outInfo.pid = app.pid;
14010 outInfo.uid = app.info.uid;
14011 if (mHeavyWeightProcess == app) {
14012 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14014 if (app.persistent) {
14015 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14017 if (app.activities.size() > 0) {
14018 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14020 outInfo.lastTrimLevel = app.trimMemoryLevel;
14021 int adj = app.curAdj;
14022 int procState = app.curProcState;
14023 outInfo.importance = procStateToImportance(procState, adj, outInfo);
14024 outInfo.importanceReasonCode = app.adjTypeCode;
14025 outInfo.processState = app.curProcState;
14029 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14030 enforceNotIsolatedCaller("getRunningAppProcesses");
14032 final int callingUid = Binder.getCallingUid();
14034 // Lazy instantiation of list
14035 List<ActivityManager.RunningAppProcessInfo> runList = null;
14036 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14037 callingUid) == PackageManager.PERMISSION_GRANTED;
14038 final int userId = UserHandle.getUserId(callingUid);
14039 final boolean allUids = isGetTasksAllowed(
14040 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14042 synchronized (this) {
14043 // Iterate across all processes
14044 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14045 ProcessRecord app = mLruProcesses.get(i);
14046 if ((!allUsers && app.userId != userId)
14047 || (!allUids && app.uid != callingUid)) {
14050 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14051 // Generate process state info for running application
14052 ActivityManager.RunningAppProcessInfo currApp =
14053 new ActivityManager.RunningAppProcessInfo(app.processName,
14054 app.pid, app.getPackageList());
14055 fillInProcMemInfo(app, currApp);
14056 if (app.adjSource instanceof ProcessRecord) {
14057 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14058 currApp.importanceReasonImportance =
14059 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14060 app.adjSourceProcState);
14061 } else if (app.adjSource instanceof ActivityRecord) {
14062 ActivityRecord r = (ActivityRecord)app.adjSource;
14063 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14065 if (app.adjTarget instanceof ComponentName) {
14066 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14068 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14069 // + " lru=" + currApp.lru);
14070 if (runList == null) {
14071 runList = new ArrayList<>();
14073 runList.add(currApp);
14081 public List<ApplicationInfo> getRunningExternalApplications() {
14082 enforceNotIsolatedCaller("getRunningExternalApplications");
14083 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14084 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14085 if (runningApps != null && runningApps.size() > 0) {
14086 Set<String> extList = new HashSet<String>();
14087 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14088 if (app.pkgList != null) {
14089 for (String pkg : app.pkgList) {
14094 IPackageManager pm = AppGlobals.getPackageManager();
14095 for (String pkg : extList) {
14097 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14098 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14101 } catch (RemoteException e) {
14109 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14110 enforceNotIsolatedCaller("getMyMemoryState");
14111 synchronized (this) {
14112 ProcessRecord proc;
14113 synchronized (mPidsSelfLocked) {
14114 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14116 fillInProcMemInfo(proc, outInfo);
14121 public int getMemoryTrimLevel() {
14122 enforceNotIsolatedCaller("getMyMemoryState");
14123 synchronized (this) {
14124 return mLastMemoryLevel;
14129 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14130 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14131 (new ActivityManagerShellCommand(this, false)).exec(
14132 this, in, out, err, args, resultReceiver);
14136 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14137 if (checkCallingPermission(android.Manifest.permission.DUMP)
14138 != PackageManager.PERMISSION_GRANTED) {
14139 pw.println("Permission Denial: can't dump ActivityManager from from pid="
14140 + Binder.getCallingPid()
14141 + ", uid=" + Binder.getCallingUid()
14142 + " without permission "
14143 + android.Manifest.permission.DUMP);
14147 boolean dumpAll = false;
14148 boolean dumpClient = false;
14149 boolean dumpCheckin = false;
14150 boolean dumpCheckinFormat = false;
14151 String dumpPackage = null;
14154 while (opti < args.length) {
14155 String opt = args[opti];
14156 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14160 if ("-a".equals(opt)) {
14162 } else if ("-c".equals(opt)) {
14164 } else if ("-p".equals(opt)) {
14165 if (opti < args.length) {
14166 dumpPackage = args[opti];
14169 pw.println("Error: -p option requires package argument");
14173 } else if ("--checkin".equals(opt)) {
14174 dumpCheckin = dumpCheckinFormat = true;
14175 } else if ("-C".equals(opt)) {
14176 dumpCheckinFormat = true;
14177 } else if ("-h".equals(opt)) {
14178 ActivityManagerShellCommand.dumpHelp(pw, true);
14181 pw.println("Unknown argument: " + opt + "; use -h for help");
14185 long origId = Binder.clearCallingIdentity();
14186 boolean more = false;
14187 // Is the caller requesting to dump a particular piece of data?
14188 if (opti < args.length) {
14189 String cmd = args[opti];
14191 if ("activities".equals(cmd) || "a".equals(cmd)) {
14192 synchronized (this) {
14193 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14195 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14196 synchronized (this) {
14197 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14199 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14202 if (opti >= args.length) {
14204 newArgs = EMPTY_STRING_ARRAY;
14206 dumpPackage = args[opti];
14208 newArgs = new String[args.length - opti];
14209 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14210 args.length - opti);
14212 synchronized (this) {
14213 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14215 } else if ("broadcast-stats".equals(cmd)) {
14218 if (opti >= args.length) {
14220 newArgs = EMPTY_STRING_ARRAY;
14222 dumpPackage = args[opti];
14224 newArgs = new String[args.length - opti];
14225 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14226 args.length - opti);
14228 synchronized (this) {
14229 if (dumpCheckinFormat) {
14230 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14233 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14236 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14239 if (opti >= args.length) {
14241 newArgs = EMPTY_STRING_ARRAY;
14243 dumpPackage = args[opti];
14245 newArgs = new String[args.length - opti];
14246 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14247 args.length - opti);
14249 synchronized (this) {
14250 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14252 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14255 if (opti >= args.length) {
14257 newArgs = EMPTY_STRING_ARRAY;
14259 dumpPackage = args[opti];
14261 newArgs = new String[args.length - opti];
14262 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14263 args.length - opti);
14265 synchronized (this) {
14266 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14268 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14269 synchronized (this) {
14270 dumpOomLocked(fd, pw, args, opti, true);
14272 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14273 synchronized (this) {
14274 dumpPermissionsLocked(fd, pw, args, opti, true, null);
14276 } else if ("provider".equals(cmd)) {
14279 if (opti >= args.length) {
14281 newArgs = EMPTY_STRING_ARRAY;
14285 newArgs = new String[args.length - opti];
14286 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14288 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14289 pw.println("No providers match: " + name);
14290 pw.println("Use -h for help.");
14292 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14293 synchronized (this) {
14294 dumpProvidersLocked(fd, pw, args, opti, true, null);
14296 } else if ("service".equals(cmd)) {
14299 if (opti >= args.length) {
14301 newArgs = EMPTY_STRING_ARRAY;
14305 newArgs = new String[args.length - opti];
14306 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14307 args.length - opti);
14309 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14310 pw.println("No services match: " + name);
14311 pw.println("Use -h for help.");
14313 } else if ("package".equals(cmd)) {
14315 if (opti >= args.length) {
14316 pw.println("package: no package name specified");
14317 pw.println("Use -h for help.");
14319 dumpPackage = args[opti];
14321 newArgs = new String[args.length - opti];
14322 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14323 args.length - opti);
14328 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14329 synchronized (this) {
14330 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14332 } else if ("services".equals(cmd) || "s".equals(cmd)) {
14334 ActiveServices.ServiceDumper dumper;
14335 synchronized (this) {
14336 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14339 dumper.dumpWithClient();
14341 synchronized (this) {
14342 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14343 dumpPackage).dumpLocked();
14346 } else if ("locks".equals(cmd)) {
14347 LockGuard.dump(fd, pw, args);
14349 // Dumping a single activity?
14350 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14351 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14352 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14354 pw.println("Bad activity command, or no activities match: " + cmd);
14355 pw.println("Use -h for help.");
14360 Binder.restoreCallingIdentity(origId);
14365 // No piece of data specified, dump everything.
14366 if (dumpCheckinFormat) {
14367 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14368 } else if (dumpClient) {
14369 ActiveServices.ServiceDumper sdumper;
14370 synchronized (this) {
14371 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14374 pw.println("-------------------------------------------------------------------------------");
14376 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14379 pw.println("-------------------------------------------------------------------------------");
14381 if (dumpAll || dumpPackage != null) {
14382 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14385 pw.println("-------------------------------------------------------------------------------");
14388 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14391 pw.println("-------------------------------------------------------------------------------");
14393 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14396 pw.println("-------------------------------------------------------------------------------");
14398 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14401 sdumper.dumpWithClient();
14403 synchronized (this) {
14405 pw.println("-------------------------------------------------------------------------------");
14407 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14410 pw.println("-------------------------------------------------------------------------------");
14412 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14413 if (mAssociations.size() > 0) {
14416 pw.println("-------------------------------------------------------------------------------");
14418 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14422 pw.println("-------------------------------------------------------------------------------");
14424 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14428 synchronized (this) {
14429 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14432 pw.println("-------------------------------------------------------------------------------");
14434 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14437 pw.println("-------------------------------------------------------------------------------");
14439 if (dumpAll || dumpPackage != null) {
14440 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14443 pw.println("-------------------------------------------------------------------------------");
14446 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14449 pw.println("-------------------------------------------------------------------------------");
14451 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14454 pw.println("-------------------------------------------------------------------------------");
14456 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14460 pw.println("-------------------------------------------------------------------------------");
14462 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14465 pw.println("-------------------------------------------------------------------------------");
14467 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14468 if (mAssociations.size() > 0) {
14471 pw.println("-------------------------------------------------------------------------------");
14473 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14477 pw.println("-------------------------------------------------------------------------------");
14479 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14482 Binder.restoreCallingIdentity(origId);
14485 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14486 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14487 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14489 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14491 boolean needSep = printedAnything;
14493 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14494 dumpPackage, needSep, " mFocusedActivity: ");
14496 printedAnything = true;
14500 if (dumpPackage == null) {
14505 printedAnything = true;
14506 mStackSupervisor.dump(pw, " ");
14509 if (!printedAnything) {
14510 pw.println(" (nothing)");
14514 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14515 int opti, boolean dumpAll, String dumpPackage) {
14516 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14518 boolean printedAnything = false;
14520 if (mRecentTasks != null && mRecentTasks.size() > 0) {
14521 boolean printedHeader = false;
14523 final int N = mRecentTasks.size();
14524 for (int i=0; i<N; i++) {
14525 TaskRecord tr = mRecentTasks.get(i);
14526 if (dumpPackage != null) {
14527 if (tr.realActivity == null ||
14528 !dumpPackage.equals(tr.realActivity)) {
14532 if (!printedHeader) {
14533 pw.println(" Recent tasks:");
14534 printedHeader = true;
14535 printedAnything = true;
14537 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
14540 mRecentTasks.get(i).dump(pw, " ");
14545 if (!printedAnything) {
14546 pw.println(" (nothing)");
14550 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14551 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14552 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14555 if (dumpPackage != null) {
14556 IPackageManager pm = AppGlobals.getPackageManager();
14558 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14559 } catch (RemoteException e) {
14563 boolean printedAnything = false;
14565 final long now = SystemClock.uptimeMillis();
14567 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14568 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14569 = mAssociations.valueAt(i1);
14570 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14571 SparseArray<ArrayMap<String, Association>> sourceUids
14572 = targetComponents.valueAt(i2);
14573 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14574 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14575 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14576 Association ass = sourceProcesses.valueAt(i4);
14577 if (dumpPackage != null) {
14578 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14579 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14583 printedAnything = true;
14585 pw.print(ass.mTargetProcess);
14587 UserHandle.formatUid(pw, ass.mTargetUid);
14589 pw.print(ass.mSourceProcess);
14591 UserHandle.formatUid(pw, ass.mSourceUid);
14594 pw.print(ass.mTargetComponent.flattenToShortString());
14597 long dur = ass.mTime;
14598 if (ass.mNesting > 0) {
14599 dur += now - ass.mStartTime;
14601 TimeUtils.formatDuration(dur, pw);
14603 pw.print(ass.mCount);
14604 pw.print(" times)");
14606 for (int i=0; i<ass.mStateTimes.length; i++) {
14607 long amt = ass.mStateTimes[i];
14608 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14609 amt += now - ass.mLastStateUptime;
14613 pw.print(ProcessList.makeProcStateString(
14614 i + ActivityManager.MIN_PROCESS_STATE));
14616 TimeUtils.formatDuration(amt, pw);
14617 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14623 if (ass.mNesting > 0) {
14624 pw.print(" Currently active: ");
14625 TimeUtils.formatDuration(now - ass.mStartTime, pw);
14634 if (!printedAnything) {
14635 pw.println(" (nothing)");
14639 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14640 String header, boolean needSep) {
14641 boolean printed = false;
14642 int whichAppId = -1;
14643 if (dumpPackage != null) {
14645 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14647 whichAppId = UserHandle.getAppId(info.uid);
14648 } catch (NameNotFoundException e) {
14649 e.printStackTrace();
14652 for (int i=0; i<uids.size(); i++) {
14653 UidRecord uidRec = uids.valueAt(i);
14654 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14663 pw.println(header);
14666 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14667 pw.print(": "); pw.println(uidRec);
14672 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14673 int opti, boolean dumpAll, String dumpPackage) {
14674 boolean needSep = false;
14675 boolean printedAnything = false;
14678 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14681 final int NP = mProcessNames.getMap().size();
14682 for (int ip=0; ip<NP; ip++) {
14683 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14684 final int NA = procs.size();
14685 for (int ia=0; ia<NA; ia++) {
14686 ProcessRecord r = procs.valueAt(ia);
14687 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14691 pw.println(" All known processes:");
14693 printedAnything = true;
14695 pw.print(r.persistent ? " *PERS*" : " *APP*");
14696 pw.print(" UID "); pw.print(procs.keyAt(ia));
14697 pw.print(" "); pw.println(r);
14699 if (r.persistent) {
14706 if (mIsolatedProcesses.size() > 0) {
14707 boolean printed = false;
14708 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14709 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14710 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14717 pw.println(" Isolated process list (sorted by uid):");
14718 printedAnything = true;
14722 pw.println(String.format("%sIsolated #%2d: %s",
14723 " ", i, r.toString()));
14727 if (mActiveUids.size() > 0) {
14728 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14729 printedAnything = needSep = true;
14732 if (mValidateUids.size() > 0) {
14733 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14734 printedAnything = needSep = true;
14738 if (mLruProcesses.size() > 0) {
14742 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14743 pw.print(" total, non-act at ");
14744 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14745 pw.print(", non-svc at ");
14746 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14748 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14750 printedAnything = true;
14753 if (dumpAll || dumpPackage != null) {
14754 synchronized (mPidsSelfLocked) {
14755 boolean printed = false;
14756 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14757 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14758 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14762 if (needSep) pw.println();
14764 pw.println(" PID mappings:");
14766 printedAnything = true;
14768 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14769 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14774 if (mForegroundProcesses.size() > 0) {
14775 synchronized (mPidsSelfLocked) {
14776 boolean printed = false;
14777 for (int i=0; i<mForegroundProcesses.size(); i++) {
14778 ProcessRecord r = mPidsSelfLocked.get(
14779 mForegroundProcesses.valueAt(i).pid);
14780 if (dumpPackage != null && (r == null
14781 || !r.pkgList.containsKey(dumpPackage))) {
14785 if (needSep) pw.println();
14787 pw.println(" Foreground Processes:");
14789 printedAnything = true;
14791 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14792 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14797 if (mPersistentStartingProcesses.size() > 0) {
14798 if (needSep) pw.println();
14800 printedAnything = true;
14801 pw.println(" Persisent processes that are starting:");
14802 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14803 "Starting Norm", "Restarting PERS", dumpPackage);
14806 if (mRemovedProcesses.size() > 0) {
14807 if (needSep) pw.println();
14809 printedAnything = true;
14810 pw.println(" Processes that are being removed:");
14811 dumpProcessList(pw, this, mRemovedProcesses, " ",
14812 "Removed Norm", "Removed PERS", dumpPackage);
14815 if (mProcessesOnHold.size() > 0) {
14816 if (needSep) pw.println();
14818 printedAnything = true;
14819 pw.println(" Processes that are on old until the system is ready:");
14820 dumpProcessList(pw, this, mProcessesOnHold, " ",
14821 "OnHold Norm", "OnHold PERS", dumpPackage);
14824 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14826 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14828 printedAnything = true;
14831 if (dumpPackage == null) {
14834 mUserController.dump(pw, dumpAll);
14836 if (mHomeProcess != null && (dumpPackage == null
14837 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14842 pw.println(" mHomeProcess: " + mHomeProcess);
14844 if (mPreviousProcess != null && (dumpPackage == null
14845 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14850 pw.println(" mPreviousProcess: " + mPreviousProcess);
14853 StringBuilder sb = new StringBuilder(128);
14854 sb.append(" mPreviousProcessVisibleTime: ");
14855 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14858 if (mHeavyWeightProcess != null && (dumpPackage == null
14859 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14864 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14866 if (dumpPackage == null) {
14867 pw.println(" mConfiguration: " + mConfiguration);
14870 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14871 if (mCompatModePackages.getPackages().size() > 0) {
14872 boolean printed = false;
14873 for (Map.Entry<String, Integer> entry
14874 : mCompatModePackages.getPackages().entrySet()) {
14875 String pkg = entry.getKey();
14876 int mode = entry.getValue();
14877 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14881 pw.println(" mScreenCompatPackages:");
14884 pw.print(" "); pw.print(pkg); pw.print(": ");
14885 pw.print(mode); pw.println();
14889 if (dumpPackage == null) {
14890 pw.println(" mWakefulness="
14891 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14892 pw.println(" mSleepTokens=" + mSleepTokens);
14893 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14894 + lockScreenShownToString());
14895 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14896 if (mRunningVoice != null) {
14897 pw.println(" mRunningVoice=" + mRunningVoice);
14898 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14901 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14902 || mOrigWaitForDebugger) {
14903 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14904 || dumpPackage.equals(mOrigDebugApp)) {
14909 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14910 + " mDebugTransient=" + mDebugTransient
14911 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14914 if (mCurAppTimeTracker != null) {
14915 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14917 if (mMemWatchProcesses.getMap().size() > 0) {
14918 pw.println(" Mem watch processes:");
14919 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14920 = mMemWatchProcesses.getMap();
14921 for (int i=0; i<procs.size(); i++) {
14922 final String proc = procs.keyAt(i);
14923 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14924 for (int j=0; j<uids.size(); j++) {
14929 StringBuilder sb = new StringBuilder();
14930 sb.append(" ").append(proc).append('/');
14931 UserHandle.formatUid(sb, uids.keyAt(j));
14932 Pair<Long, String> val = uids.valueAt(j);
14933 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14934 if (val.second != null) {
14935 sb.append(", report to ").append(val.second);
14937 pw.println(sb.toString());
14940 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14941 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14942 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14943 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14945 if (mTrackAllocationApp != null) {
14946 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14951 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14954 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14955 || mProfileFd != null) {
14956 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14961 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14962 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14963 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14964 + mAutoStopProfiler);
14965 pw.println(" mProfileType=" + mProfileType);
14968 if (mNativeDebuggingApp != null) {
14969 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14974 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14977 if (dumpPackage == null) {
14978 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14979 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14980 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14982 if (mController != null) {
14983 pw.println(" mController=" + mController
14984 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14987 pw.println(" Total persistent processes: " + numPers);
14988 pw.println(" mProcessesReady=" + mProcessesReady
14989 + " mSystemReady=" + mSystemReady
14990 + " mBooted=" + mBooted
14991 + " mFactoryTest=" + mFactoryTest);
14992 pw.println(" mBooting=" + mBooting
14993 + " mCallFinishBooting=" + mCallFinishBooting
14994 + " mBootAnimationComplete=" + mBootAnimationComplete);
14995 pw.print(" mLastPowerCheckRealtime=");
14996 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14998 pw.print(" mLastPowerCheckUptime=");
14999 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15001 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15002 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15003 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15004 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
15005 + " (" + mLruProcesses.size() + " total)"
15006 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15007 + " mNumServiceProcs=" + mNumServiceProcs
15008 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15009 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
15010 + " mLastMemoryLevel=" + mLastMemoryLevel
15011 + " mLastNumProcesses=" + mLastNumProcesses);
15012 long now = SystemClock.uptimeMillis();
15013 pw.print(" mLastIdleTime=");
15014 TimeUtils.formatDuration(now, mLastIdleTime, pw);
15015 pw.print(" mLowRamSinceLastIdle=");
15016 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15021 if (!printedAnything) {
15022 pw.println(" (nothing)");
15026 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15027 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15028 if (mProcessesToGc.size() > 0) {
15029 boolean printed = false;
15030 long now = SystemClock.uptimeMillis();
15031 for (int i=0; i<mProcessesToGc.size(); i++) {
15032 ProcessRecord proc = mProcessesToGc.get(i);
15033 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15037 if (needSep) pw.println();
15039 pw.println(" Processes that are waiting to GC:");
15042 pw.print(" Process "); pw.println(proc);
15043 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
15044 pw.print(", last gced=");
15045 pw.print(now-proc.lastRequestedGc);
15046 pw.print(" ms ago, last lowMem=");
15047 pw.print(now-proc.lastLowMemory);
15048 pw.println(" ms ago");
15055 void printOomLevel(PrintWriter pw, String name, int adj) {
15059 if (adj < 10) pw.print(' ');
15061 if (adj > -10) pw.print(' ');
15067 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15071 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15072 int opti, boolean dumpAll) {
15073 boolean needSep = false;
15075 if (mLruProcesses.size() > 0) {
15076 if (needSep) pw.println();
15078 pw.println(" OOM levels:");
15079 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15080 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15081 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15082 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15083 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15084 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15085 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15086 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15087 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15088 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15089 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15090 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15091 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15092 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15094 if (needSep) pw.println();
15095 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
15096 pw.print(" total, non-act at ");
15097 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15098 pw.print(", non-svc at ");
15099 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15101 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
15105 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15108 pw.println(" mHomeProcess: " + mHomeProcess);
15109 pw.println(" mPreviousProcess: " + mPreviousProcess);
15110 if (mHeavyWeightProcess != null) {
15111 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15118 * There are three ways to call this:
15119 * - no provider specified: dump all the providers
15120 * - a flattened component name that matched an existing provider was specified as the
15121 * first arg: dump that one provider
15122 * - the first arg isn't the flattened component name of an existing provider:
15123 * dump all providers whose component contains the first arg as a substring
15125 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15126 int opti, boolean dumpAll) {
15127 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15130 static class ItemMatcher {
15131 ArrayList<ComponentName> components;
15132 ArrayList<String> strings;
15133 ArrayList<Integer> objects;
15140 void build(String name) {
15141 ComponentName componentName = ComponentName.unflattenFromString(name);
15142 if (componentName != null) {
15143 if (components == null) {
15144 components = new ArrayList<ComponentName>();
15146 components.add(componentName);
15150 // Not a '/' separated full component name; maybe an object ID?
15152 objectId = Integer.parseInt(name, 16);
15153 if (objects == null) {
15154 objects = new ArrayList<Integer>();
15156 objects.add(objectId);
15158 } catch (RuntimeException e) {
15159 // Not an integer; just do string match.
15160 if (strings == null) {
15161 strings = new ArrayList<String>();
15169 int build(String[] args, int opti) {
15170 for (; opti<args.length; opti++) {
15171 String name = args[opti];
15172 if ("--".equals(name)) {
15180 boolean match(Object object, ComponentName comp) {
15184 if (components != null) {
15185 for (int i=0; i<components.size(); i++) {
15186 if (components.get(i).equals(comp)) {
15191 if (objects != null) {
15192 for (int i=0; i<objects.size(); i++) {
15193 if (System.identityHashCode(object) == objects.get(i)) {
15198 if (strings != null) {
15199 String flat = comp.flattenToString();
15200 for (int i=0; i<strings.size(); i++) {
15201 if (flat.contains(strings.get(i))) {
15211 * There are three things that cmd can be:
15212 * - a flattened component name that matches an existing activity
15213 * - the cmd arg isn't the flattened component name of an existing activity:
15214 * dump all activity whose component contains the cmd as a substring
15215 * - A hex number of the ActivityRecord object instance.
15217 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15218 int opti, boolean dumpAll) {
15219 ArrayList<ActivityRecord> activities;
15221 synchronized (this) {
15222 activities = mStackSupervisor.getDumpActivitiesLocked(name);
15225 if (activities.size() <= 0) {
15229 String[] newArgs = new String[args.length - opti];
15230 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15232 TaskRecord lastTask = null;
15233 boolean needSep = false;
15234 for (int i=activities.size()-1; i>=0; i--) {
15235 ActivityRecord r = activities.get(i);
15240 synchronized (this) {
15241 if (lastTask != r.task) {
15243 pw.print("TASK "); pw.print(lastTask.affinity);
15244 pw.print(" id="); pw.println(lastTask.taskId);
15246 lastTask.dump(pw, " ");
15250 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
15256 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15257 * there is a thread associated with the activity.
15259 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15260 final ActivityRecord r, String[] args, boolean dumpAll) {
15261 String innerPrefix = prefix + " ";
15262 synchronized (this) {
15263 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15264 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15266 if (r.app != null) pw.println(r.app.pid);
15267 else pw.println("(not running)");
15269 r.dump(pw, innerPrefix);
15272 if (r.app != null && r.app.thread != null) {
15273 // flush anything that is already in the PrintWriter since the thread is going
15274 // to write to the file descriptor directly
15277 TransferPipe tp = new TransferPipe();
15279 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15280 r.appToken, innerPrefix, args);
15285 } catch (IOException e) {
15286 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15287 } catch (RemoteException e) {
15288 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15293 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15294 int opti, boolean dumpAll, String dumpPackage) {
15295 boolean needSep = false;
15296 boolean onlyHistory = false;
15297 boolean printedAnything = false;
15299 if ("history".equals(dumpPackage)) {
15300 if (opti < args.length && "-s".equals(args[opti])) {
15303 onlyHistory = true;
15304 dumpPackage = null;
15307 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15308 if (!onlyHistory && dumpAll) {
15309 if (mRegisteredReceivers.size() > 0) {
15310 boolean printed = false;
15311 Iterator it = mRegisteredReceivers.values().iterator();
15312 while (it.hasNext()) {
15313 ReceiverList r = (ReceiverList)it.next();
15314 if (dumpPackage != null && (r.app == null ||
15315 !dumpPackage.equals(r.app.info.packageName))) {
15319 pw.println(" Registered Receivers:");
15322 printedAnything = true;
15324 pw.print(" * "); pw.println(r);
15329 if (mReceiverResolver.dump(pw, needSep ?
15330 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
15331 " ", dumpPackage, false, false)) {
15333 printedAnything = true;
15337 for (BroadcastQueue q : mBroadcastQueues) {
15338 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15339 printedAnything |= needSep;
15344 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15345 for (int user=0; user<mStickyBroadcasts.size(); user++) {
15350 printedAnything = true;
15351 pw.print(" Sticky broadcasts for user ");
15352 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15353 StringBuilder sb = new StringBuilder(128);
15354 for (Map.Entry<String, ArrayList<Intent>> ent
15355 : mStickyBroadcasts.valueAt(user).entrySet()) {
15356 pw.print(" * Sticky action "); pw.print(ent.getKey());
15359 ArrayList<Intent> intents = ent.getValue();
15360 final int N = intents.size();
15361 for (int i=0; i<N; i++) {
15363 sb.append(" Intent: ");
15364 intents.get(i).toShortString(sb, false, true, false, false);
15365 pw.println(sb.toString());
15366 Bundle bundle = intents.get(i).getExtras();
15367 if (bundle != null) {
15369 pw.println(bundle.toString());
15379 if (!onlyHistory && dumpAll) {
15381 for (BroadcastQueue queue : mBroadcastQueues) {
15382 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
15383 + queue.mBroadcastsScheduled);
15385 pw.println(" mHandler:");
15386 mHandler.dump(new PrintWriterPrinter(pw), " ");
15388 printedAnything = true;
15391 if (!printedAnything) {
15392 pw.println(" (nothing)");
15396 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15397 int opti, boolean dumpAll, String dumpPackage) {
15398 if (mCurBroadcastStats == null) {
15402 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15403 final long now = SystemClock.elapsedRealtime();
15404 if (mLastBroadcastStats != null) {
15405 pw.print(" Last stats (from ");
15406 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15408 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15410 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15411 - mLastBroadcastStats.mStartUptime, pw);
15412 pw.println(" uptime):");
15413 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15414 pw.println(" (nothing)");
15418 pw.print(" Current stats (from ");
15419 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15420 pw.print(" to now, ");
15421 TimeUtils.formatDuration(SystemClock.uptimeMillis()
15422 - mCurBroadcastStats.mStartUptime, pw);
15423 pw.println(" uptime):");
15424 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15425 pw.println(" (nothing)");
15429 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15430 int opti, boolean fullCheckin, String dumpPackage) {
15431 if (mCurBroadcastStats == null) {
15435 if (mLastBroadcastStats != null) {
15436 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15438 mLastBroadcastStats = null;
15442 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15444 mCurBroadcastStats = null;
15448 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15449 int opti, boolean dumpAll, String dumpPackage) {
15451 boolean printedAnything = false;
15453 ItemMatcher matcher = new ItemMatcher();
15454 matcher.build(args, opti);
15456 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15458 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15459 printedAnything |= needSep;
15461 if (mLaunchingProviders.size() > 0) {
15462 boolean printed = false;
15463 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15464 ContentProviderRecord r = mLaunchingProviders.get(i);
15465 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15469 if (needSep) pw.println();
15471 pw.println(" Launching content providers:");
15473 printedAnything = true;
15475 pw.print(" Launching #"); pw.print(i); pw.print(": ");
15480 if (!printedAnything) {
15481 pw.println(" (nothing)");
15485 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15486 int opti, boolean dumpAll, String dumpPackage) {
15487 boolean needSep = false;
15488 boolean printedAnything = false;
15490 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15492 if (mGrantedUriPermissions.size() > 0) {
15493 boolean printed = false;
15495 if (dumpPackage != null) {
15497 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15498 MATCH_UNINSTALLED_PACKAGES, 0);
15499 } catch (NameNotFoundException e) {
15503 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15504 int uid = mGrantedUriPermissions.keyAt(i);
15505 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15508 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15510 if (needSep) pw.println();
15512 pw.println(" Granted Uri Permissions:");
15514 printedAnything = true;
15516 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
15517 for (UriPermission perm : perms.values()) {
15518 pw.print(" "); pw.println(perm);
15520 perm.dump(pw, " ");
15526 if (!printedAnything) {
15527 pw.println(" (nothing)");
15531 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15532 int opti, boolean dumpAll, String dumpPackage) {
15533 boolean printed = false;
15535 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15537 if (mIntentSenderRecords.size() > 0) {
15538 Iterator<WeakReference<PendingIntentRecord>> it
15539 = mIntentSenderRecords.values().iterator();
15540 while (it.hasNext()) {
15541 WeakReference<PendingIntentRecord> ref = it.next();
15542 PendingIntentRecord rec = ref != null ? ref.get(): null;
15543 if (dumpPackage != null && (rec == null
15544 || !dumpPackage.equals(rec.key.packageName))) {
15549 pw.print(" * "); pw.println(rec);
15554 pw.print(" * "); pw.println(ref);
15560 pw.println(" (nothing)");
15564 private static final int dumpProcessList(PrintWriter pw,
15565 ActivityManagerService service, List list,
15566 String prefix, String normalLabel, String persistentLabel,
15567 String dumpPackage) {
15569 final int N = list.size()-1;
15570 for (int i=N; i>=0; i--) {
15571 ProcessRecord r = (ProcessRecord)list.get(i);
15572 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15575 pw.println(String.format("%s%s #%2d: %s",
15576 prefix, (r.persistent ? persistentLabel : normalLabel),
15578 if (r.persistent) {
15585 private static final boolean dumpProcessOomList(PrintWriter pw,
15586 ActivityManagerService service, List<ProcessRecord> origList,
15587 String prefix, String normalLabel, String persistentLabel,
15588 boolean inclDetails, String dumpPackage) {
15590 ArrayList<Pair<ProcessRecord, Integer>> list
15591 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15592 for (int i=0; i<origList.size(); i++) {
15593 ProcessRecord r = origList.get(i);
15594 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15597 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15600 if (list.size() <= 0) {
15604 Comparator<Pair<ProcessRecord, Integer>> comparator
15605 = new Comparator<Pair<ProcessRecord, Integer>>() {
15607 public int compare(Pair<ProcessRecord, Integer> object1,
15608 Pair<ProcessRecord, Integer> object2) {
15609 if (object1.first.setAdj != object2.first.setAdj) {
15610 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15612 if (object1.first.setProcState != object2.first.setProcState) {
15613 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15615 if (object1.second.intValue() != object2.second.intValue()) {
15616 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15622 Collections.sort(list, comparator);
15624 final long curRealtime = SystemClock.elapsedRealtime();
15625 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15626 final long curUptime = SystemClock.uptimeMillis();
15627 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15629 for (int i=list.size()-1; i>=0; i--) {
15630 ProcessRecord r = list.get(i).first;
15631 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15633 switch (r.setSchedGroup) {
15634 case ProcessList.SCHED_GROUP_BACKGROUND:
15637 case ProcessList.SCHED_GROUP_DEFAULT:
15640 case ProcessList.SCHED_GROUP_TOP_APP:
15648 if (r.foregroundActivities) {
15650 } else if (r.foregroundServices) {
15655 String procState = ProcessList.makeProcStateString(r.curProcState);
15657 pw.print(r.persistent ? persistentLabel : normalLabel);
15659 int num = (origList.size()-1)-list.get(i).second;
15660 if (num < 10) pw.print(' ');
15665 pw.print(schedGroup);
15667 pw.print(foreground);
15669 pw.print(procState);
15671 if (r.trimMemoryLevel < 10) pw.print(' ');
15672 pw.print(r.trimMemoryLevel);
15674 pw.print(r.toShortString());
15676 pw.print(r.adjType);
15678 if (r.adjSource != null || r.adjTarget != null) {
15681 if (r.adjTarget instanceof ComponentName) {
15682 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15683 } else if (r.adjTarget != null) {
15684 pw.print(r.adjTarget.toString());
15686 pw.print("{null}");
15689 if (r.adjSource instanceof ProcessRecord) {
15691 pw.print(((ProcessRecord)r.adjSource).toShortString());
15693 } else if (r.adjSource != null) {
15694 pw.println(r.adjSource.toString());
15696 pw.println("{null}");
15702 pw.print("oom: max="); pw.print(r.maxAdj);
15703 pw.print(" curRaw="); pw.print(r.curRawAdj);
15704 pw.print(" setRaw="); pw.print(r.setRawAdj);
15705 pw.print(" cur="); pw.print(r.curAdj);
15706 pw.print(" set="); pw.println(r.setAdj);
15709 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15710 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15711 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15712 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15713 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15717 pw.print("cached="); pw.print(r.cached);
15718 pw.print(" empty="); pw.print(r.empty);
15719 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15721 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15722 if (r.lastWakeTime != 0) {
15724 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15725 synchronized (stats) {
15726 wtime = stats.getProcessWakeTime(r.info.uid,
15727 r.pid, curRealtime);
15729 long timeUsed = wtime - r.lastWakeTime;
15732 pw.print("keep awake over ");
15733 TimeUtils.formatDuration(realtimeSince, pw);
15734 pw.print(" used ");
15735 TimeUtils.formatDuration(timeUsed, pw);
15737 pw.print((timeUsed*100)/realtimeSince);
15740 if (r.lastCpuTime != 0) {
15741 long timeUsed = r.curCpuTime - r.lastCpuTime;
15744 pw.print("run cpu over ");
15745 TimeUtils.formatDuration(uptimeSince, pw);
15746 pw.print(" used ");
15747 TimeUtils.formatDuration(timeUsed, pw);
15749 pw.print((timeUsed*100)/uptimeSince);
15758 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15760 ArrayList<ProcessRecord> procs;
15761 synchronized (this) {
15762 if (args != null && args.length > start
15763 && args[start].charAt(0) != '-') {
15764 procs = new ArrayList<ProcessRecord>();
15767 pid = Integer.parseInt(args[start]);
15768 } catch (NumberFormatException e) {
15770 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15771 ProcessRecord proc = mLruProcesses.get(i);
15772 if (proc.pid == pid) {
15774 } else if (allPkgs && proc.pkgList != null
15775 && proc.pkgList.containsKey(args[start])) {
15777 } else if (proc.processName.equals(args[start])) {
15781 if (procs.size() <= 0) {
15785 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15791 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15792 PrintWriter pw, String[] args) {
15793 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15794 if (procs == null) {
15795 pw.println("No process found for: " + args[0]);
15799 long uptime = SystemClock.uptimeMillis();
15800 long realtime = SystemClock.elapsedRealtime();
15801 pw.println("Applications Graphics Acceleration Info:");
15802 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15804 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15805 ProcessRecord r = procs.get(i);
15806 if (r.thread != null) {
15807 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15810 TransferPipe tp = new TransferPipe();
15812 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15817 } catch (IOException e) {
15818 pw.println("Failure while dumping the app: " + r);
15820 } catch (RemoteException e) {
15821 pw.println("Got a RemoteException while dumping the app " + r);
15828 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15829 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15830 if (procs == null) {
15831 pw.println("No process found for: " + args[0]);
15835 pw.println("Applications Database Info:");
15837 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15838 ProcessRecord r = procs.get(i);
15839 if (r.thread != null) {
15840 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15843 TransferPipe tp = new TransferPipe();
15845 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15850 } catch (IOException e) {
15851 pw.println("Failure while dumping the app: " + r);
15853 } catch (RemoteException e) {
15854 pw.println("Got a RemoteException while dumping the app " + r);
15861 final static class MemItem {
15862 final boolean isProc;
15863 final String label;
15864 final String shortLabel;
15866 final long swapPss;
15868 final boolean hasActivities;
15869 ArrayList<MemItem> subitems;
15871 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15872 boolean _hasActivities) {
15875 shortLabel = _shortLabel;
15877 swapPss = _swapPss;
15879 hasActivities = _hasActivities;
15882 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15885 shortLabel = _shortLabel;
15887 swapPss = _swapPss;
15889 hasActivities = false;
15893 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15894 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15895 if (sort && !isCompact) {
15896 Collections.sort(items, new Comparator<MemItem>() {
15898 public int compare(MemItem lhs, MemItem rhs) {
15899 if (lhs.pss < rhs.pss) {
15901 } else if (lhs.pss > rhs.pss) {
15909 for (int i=0; i<items.size(); i++) {
15910 MemItem mi = items.get(i);
15913 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15914 mi.label, stringifyKBSize(mi.swapPss));
15916 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15918 } else if (mi.isProc) {
15919 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15920 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15921 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15922 pw.println(mi.hasActivities ? ",a" : ",e");
15924 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15925 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15927 if (mi.subitems != null) {
15928 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15929 true, isCompact, dumpSwapPss);
15934 // These are in KB.
15935 static final long[] DUMP_MEM_BUCKETS = new long[] {
15936 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15937 120*1024, 160*1024, 200*1024,
15938 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15939 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15942 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15943 boolean stackLike) {
15944 int start = label.lastIndexOf('.');
15945 if (start >= 0) start++;
15947 int end = label.length();
15948 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15949 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15950 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15951 out.append(bucket);
15952 out.append(stackLike ? "MB." : "MB ");
15953 out.append(label, start, end);
15957 out.append(memKB/1024);
15958 out.append(stackLike ? "MB." : "MB ");
15959 out.append(label, start, end);
15962 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15963 ProcessList.NATIVE_ADJ,
15964 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15965 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15966 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15967 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15968 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15969 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15971 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15973 "System", "Persistent", "Persistent Service", "Foreground",
15974 "Visible", "Perceptible",
15975 "Heavy Weight", "Backup",
15976 "A Services", "Home",
15977 "Previous", "B Services", "Cached"
15979 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15981 "sys", "pers", "persvc", "fore",
15984 "servicea", "home",
15985 "prev", "serviceb", "cached"
15988 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15989 long realtime, boolean isCheckinRequest, boolean isCompact) {
15991 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15993 if (isCheckinRequest || isCompact) {
15994 // short checkin version
15995 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15997 pw.println("Applications Memory Usage (in Kilobytes):");
15998 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16002 private static final int KSM_SHARED = 0;
16003 private static final int KSM_SHARING = 1;
16004 private static final int KSM_UNSHARED = 2;
16005 private static final int KSM_VOLATILE = 3;
16007 private final long[] getKsmInfo() {
16008 long[] longOut = new long[4];
16009 final int[] SINGLE_LONG_FORMAT = new int[] {
16010 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16012 long[] longTmp = new long[1];
16013 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16014 SINGLE_LONG_FORMAT, null, longTmp, null);
16015 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16017 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16018 SINGLE_LONG_FORMAT, null, longTmp, null);
16019 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16021 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16022 SINGLE_LONG_FORMAT, null, longTmp, null);
16023 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16025 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16026 SINGLE_LONG_FORMAT, null, longTmp, null);
16027 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16031 private static String stringifySize(long size, int order) {
16032 Locale locale = Locale.US;
16035 return String.format(locale, "%,13d", size);
16037 return String.format(locale, "%,9dK", size / 1024);
16039 return String.format(locale, "%,5dM", size / 1024 / 1024);
16040 case 1024 * 1024 * 1024:
16041 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16043 throw new IllegalArgumentException("Invalid size order");
16047 private static String stringifyKBSize(long size) {
16048 return stringifySize(size * 1024, 1024);
16051 // Update this version number in case you change the 'compact' format
16052 private static final int MEMINFO_COMPACT_VERSION = 1;
16054 final void dumpApplicationMemoryUsage(FileDescriptor fd,
16055 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16056 boolean dumpDetails = false;
16057 boolean dumpFullDetails = false;
16058 boolean dumpDalvik = false;
16059 boolean dumpSummaryOnly = false;
16060 boolean dumpUnreachable = false;
16061 boolean oomOnly = false;
16062 boolean isCompact = false;
16063 boolean localOnly = false;
16064 boolean packages = false;
16065 boolean isCheckinRequest = false;
16066 boolean dumpSwapPss = false;
16069 while (opti < args.length) {
16070 String opt = args[opti];
16071 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16075 if ("-a".equals(opt)) {
16076 dumpDetails = true;
16077 dumpFullDetails = true;
16079 dumpSwapPss = true;
16080 } else if ("-d".equals(opt)) {
16082 } else if ("-c".equals(opt)) {
16084 } else if ("-s".equals(opt)) {
16085 dumpDetails = true;
16086 dumpSummaryOnly = true;
16087 } else if ("-S".equals(opt)) {
16088 dumpSwapPss = true;
16089 } else if ("--unreachable".equals(opt)) {
16090 dumpUnreachable = true;
16091 } else if ("--oom".equals(opt)) {
16093 } else if ("--local".equals(opt)) {
16095 } else if ("--package".equals(opt)) {
16097 } else if ("--checkin".equals(opt)) {
16098 isCheckinRequest = true;
16100 } else if ("-h".equals(opt)) {
16101 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16102 pw.println(" -a: include all available information for each process.");
16103 pw.println(" -d: include dalvik details.");
16104 pw.println(" -c: dump in a compact machine-parseable representation.");
16105 pw.println(" -s: dump only summary of application memory usage.");
16106 pw.println(" -S: dump also SwapPss.");
16107 pw.println(" --oom: only show processes organized by oom adj.");
16108 pw.println(" --local: only collect details locally, don't call process.");
16109 pw.println(" --package: interpret process arg as package, dumping all");
16110 pw.println(" processes that have loaded that package.");
16111 pw.println(" --checkin: dump data for a checkin");
16112 pw.println("If [process] is specified it can be the name or ");
16113 pw.println("pid of a specific process to dump.");
16116 pw.println("Unknown argument: " + opt + "; use -h for help");
16120 long uptime = SystemClock.uptimeMillis();
16121 long realtime = SystemClock.elapsedRealtime();
16122 final long[] tmpLong = new long[1];
16124 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16125 if (procs == null) {
16126 // No Java processes. Maybe they want to print a native process.
16127 if (args != null && args.length > opti
16128 && args[opti].charAt(0) != '-') {
16129 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16130 = new ArrayList<ProcessCpuTracker.Stats>();
16131 updateCpuStatsNow();
16134 findPid = Integer.parseInt(args[opti]);
16135 } catch (NumberFormatException e) {
16137 synchronized (mProcessCpuTracker) {
16138 final int N = mProcessCpuTracker.countStats();
16139 for (int i=0; i<N; i++) {
16140 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16141 if (st.pid == findPid || (st.baseName != null
16142 && st.baseName.equals(args[opti]))) {
16143 nativeProcs.add(st);
16147 if (nativeProcs.size() > 0) {
16148 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16150 Debug.MemoryInfo mi = null;
16151 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16152 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16153 final int pid = r.pid;
16154 if (!isCheckinRequest && dumpDetails) {
16155 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16158 mi = new Debug.MemoryInfo();
16160 if (dumpDetails || (!brief && !oomOnly)) {
16161 Debug.getMemoryInfo(pid, mi);
16163 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16164 mi.dalvikPrivateDirty = (int)tmpLong[0];
16166 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16167 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16168 if (isCheckinRequest) {
16175 pw.println("No process found for: " + args[opti]);
16179 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16180 dumpDetails = true;
16183 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16185 String[] innerArgs = new String[args.length-opti];
16186 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16188 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16189 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16190 long nativePss = 0;
16191 long nativeSwapPss = 0;
16192 long dalvikPss = 0;
16193 long dalvikSwapPss = 0;
16194 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16196 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16199 long otherSwapPss = 0;
16200 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16201 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16203 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16204 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16205 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16206 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16209 long totalSwapPss = 0;
16210 long cachedPss = 0;
16211 long cachedSwapPss = 0;
16212 boolean hasSwapPss = false;
16214 Debug.MemoryInfo mi = null;
16215 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16216 final ProcessRecord r = procs.get(i);
16217 final IApplicationThread thread;
16220 final boolean hasActivities;
16221 synchronized (this) {
16224 oomAdj = r.getSetAdjWithServices();
16225 hasActivities = r.activities.size() > 0;
16227 if (thread != null) {
16228 if (!isCheckinRequest && dumpDetails) {
16229 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16232 mi = new Debug.MemoryInfo();
16234 if (dumpDetails || (!brief && !oomOnly)) {
16235 Debug.getMemoryInfo(pid, mi);
16236 hasSwapPss = mi.hasSwappedOutPss;
16238 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16239 mi.dalvikPrivateDirty = (int)tmpLong[0];
16243 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16244 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16245 if (isCheckinRequest) {
16251 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16252 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16253 } catch (RemoteException e) {
16254 if (!isCheckinRequest) {
16255 pw.println("Got RemoteException!");
16262 final long myTotalPss = mi.getTotalPss();
16263 final long myTotalUss = mi.getTotalUss();
16264 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16266 synchronized (this) {
16267 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16268 // Record this for posterity if the process has been stable.
16269 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16273 if (!isCheckinRequest && mi != null) {
16274 totalPss += myTotalPss;
16275 totalSwapPss += myTotalSwapPss;
16276 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16277 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16278 myTotalSwapPss, pid, hasActivities);
16279 procMems.add(pssItem);
16280 procMemsMap.put(pid, pssItem);
16282 nativePss += mi.nativePss;
16283 nativeSwapPss += mi.nativeSwappedOutPss;
16284 dalvikPss += mi.dalvikPss;
16285 dalvikSwapPss += mi.dalvikSwappedOutPss;
16286 for (int j=0; j<dalvikSubitemPss.length; j++) {
16287 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16288 dalvikSubitemSwapPss[j] +=
16289 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16291 otherPss += mi.otherPss;
16292 otherSwapPss += mi.otherSwappedOutPss;
16293 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16294 long mem = mi.getOtherPss(j);
16297 mem = mi.getOtherSwappedOutPss(j);
16298 miscSwapPss[j] += mem;
16299 otherSwapPss -= mem;
16302 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16303 cachedPss += myTotalPss;
16304 cachedSwapPss += myTotalSwapPss;
16307 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16308 if (oomIndex == (oomPss.length - 1)
16309 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16310 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16311 oomPss[oomIndex] += myTotalPss;
16312 oomSwapPss[oomIndex] += myTotalSwapPss;
16313 if (oomProcs[oomIndex] == null) {
16314 oomProcs[oomIndex] = new ArrayList<MemItem>();
16316 oomProcs[oomIndex].add(pssItem);
16324 long nativeProcTotalPss = 0;
16326 if (!isCheckinRequest && procs.size() > 1 && !packages) {
16327 // If we are showing aggregations, also look for native processes to
16328 // include so that our aggregations are more accurate.
16329 updateCpuStatsNow();
16331 synchronized (mProcessCpuTracker) {
16332 final int N = mProcessCpuTracker.countStats();
16333 for (int i=0; i<N; i++) {
16334 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16335 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16337 mi = new Debug.MemoryInfo();
16339 if (!brief && !oomOnly) {
16340 Debug.getMemoryInfo(st.pid, mi);
16342 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16343 mi.nativePrivateDirty = (int)tmpLong[0];
16346 final long myTotalPss = mi.getTotalPss();
16347 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16348 totalPss += myTotalPss;
16349 nativeProcTotalPss += myTotalPss;
16351 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16352 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16353 procMems.add(pssItem);
16355 nativePss += mi.nativePss;
16356 nativeSwapPss += mi.nativeSwappedOutPss;
16357 dalvikPss += mi.dalvikPss;
16358 dalvikSwapPss += mi.dalvikSwappedOutPss;
16359 for (int j=0; j<dalvikSubitemPss.length; j++) {
16360 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16361 dalvikSubitemSwapPss[j] +=
16362 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16364 otherPss += mi.otherPss;
16365 otherSwapPss += mi.otherSwappedOutPss;
16366 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16367 long mem = mi.getOtherPss(j);
16370 mem = mi.getOtherSwappedOutPss(j);
16371 miscSwapPss[j] += mem;
16372 otherSwapPss -= mem;
16374 oomPss[0] += myTotalPss;
16375 oomSwapPss[0] += myTotalSwapPss;
16376 if (oomProcs[0] == null) {
16377 oomProcs[0] = new ArrayList<MemItem>();
16379 oomProcs[0].add(pssItem);
16384 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16386 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16387 final MemItem dalvikItem =
16388 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16389 if (dalvikSubitemPss.length > 0) {
16390 dalvikItem.subitems = new ArrayList<MemItem>();
16391 for (int j=0; j<dalvikSubitemPss.length; j++) {
16392 final String name = Debug.MemoryInfo.getOtherLabel(
16393 Debug.MemoryInfo.NUM_OTHER_STATS + j);
16394 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16395 dalvikSubitemSwapPss[j], j));
16398 catMems.add(dalvikItem);
16399 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16400 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16401 String label = Debug.MemoryInfo.getOtherLabel(j);
16402 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16405 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16406 for (int j=0; j<oomPss.length; j++) {
16407 if (oomPss[j] != 0) {
16408 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16409 : DUMP_MEM_OOM_LABEL[j];
16410 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16411 DUMP_MEM_OOM_ADJ[j]);
16412 item.subitems = oomProcs[j];
16417 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16418 if (!brief && !oomOnly && !isCompact) {
16420 pw.println("Total PSS by process:");
16421 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
16425 pw.println("Total PSS by OOM adjustment:");
16427 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
16428 if (!brief && !oomOnly) {
16429 PrintWriter out = categoryPw != null ? categoryPw : pw;
16432 out.println("Total PSS by category:");
16434 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
16439 MemInfoReader memInfo = new MemInfoReader();
16440 memInfo.readMemInfo();
16441 if (nativeProcTotalPss > 0) {
16442 synchronized (this) {
16443 final long cachedKb = memInfo.getCachedSizeKb();
16444 final long freeKb = memInfo.getFreeSizeKb();
16445 final long zramKb = memInfo.getZramTotalSizeKb();
16446 final long kernelKb = memInfo.getKernelUsedSizeKb();
16447 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16448 kernelKb*1024, nativeProcTotalPss*1024);
16449 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16450 nativeProcTotalPss);
16455 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16456 pw.print(" (status ");
16457 switch (mLastMemoryLevel) {
16458 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16459 pw.println("normal)");
16461 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16462 pw.println("moderate)");
16464 case ProcessStats.ADJ_MEM_FACTOR_LOW:
16465 pw.println("low)");
16467 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16468 pw.println("critical)");
16471 pw.print(mLastMemoryLevel);
16475 pw.print(" Free RAM: ");
16476 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16477 + memInfo.getFreeSizeKb()));
16479 pw.print(stringifyKBSize(cachedPss));
16480 pw.print(" cached pss + ");
16481 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16482 pw.print(" cached kernel + ");
16483 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16484 pw.println(" free)");
16486 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16487 pw.print(cachedPss + memInfo.getCachedSizeKb()
16488 + memInfo.getFreeSizeKb()); pw.print(",");
16489 pw.println(totalPss - cachedPss);
16492 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16493 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16494 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16496 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16497 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16498 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16499 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16500 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16502 pw.print("lostram,"); pw.println(lostRAM);
16505 if (memInfo.getZramTotalSizeKb() != 0) {
16507 pw.print(" ZRAM: ");
16508 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16509 pw.print(" physical used for ");
16510 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16511 - memInfo.getSwapFreeSizeKb()));
16512 pw.print(" in swap (");
16513 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16514 pw.println(" total swap)");
16516 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16517 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16518 pw.println(memInfo.getSwapFreeSizeKb());
16521 final long[] ksm = getKsmInfo();
16523 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16524 || ksm[KSM_VOLATILE] != 0) {
16525 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16526 pw.print(" saved from shared ");
16527 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16528 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16529 pw.print(" unshared; ");
16530 pw.print(stringifyKBSize(
16531 ksm[KSM_VOLATILE])); pw.println(" volatile");
16533 pw.print(" Tuning: ");
16534 pw.print(ActivityManager.staticGetMemoryClass());
16535 pw.print(" (large ");
16536 pw.print(ActivityManager.staticGetLargeMemoryClass());
16537 pw.print("), oom ");
16538 pw.print(stringifySize(
16539 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16540 pw.print(", restore limit ");
16541 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16542 if (ActivityManager.isLowRamDeviceStatic()) {
16543 pw.print(" (low-ram)");
16545 if (ActivityManager.isHighEndGfx()) {
16546 pw.print(" (high-end-gfx)");
16550 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16551 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16552 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16553 pw.print("tuning,");
16554 pw.print(ActivityManager.staticGetMemoryClass());
16556 pw.print(ActivityManager.staticGetLargeMemoryClass());
16558 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16559 if (ActivityManager.isLowRamDeviceStatic()) {
16560 pw.print(",low-ram");
16562 if (ActivityManager.isHighEndGfx()) {
16563 pw.print(",high-end-gfx");
16571 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16572 long memtrack, String name) {
16574 sb.append(ProcessList.makeOomAdjString(oomAdj));
16576 sb.append(ProcessList.makeProcStateString(procState));
16578 ProcessList.appendRamKb(sb, pss);
16581 if (memtrack > 0) {
16583 sb.append(stringifyKBSize(memtrack));
16584 sb.append(" memtrack)");
16588 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16589 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16590 sb.append(" (pid ");
16593 sb.append(mi.adjType);
16595 if (mi.adjReason != null) {
16597 sb.append(mi.adjReason);
16602 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16603 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16604 for (int i=0, N=memInfos.size(); i<N; i++) {
16605 ProcessMemInfo mi = memInfos.get(i);
16606 infoMap.put(mi.pid, mi);
16608 updateCpuStatsNow();
16609 long[] memtrackTmp = new long[1];
16610 final List<ProcessCpuTracker.Stats> stats;
16611 // Get a list of Stats that have vsize > 0
16612 synchronized (mProcessCpuTracker) {
16613 stats = mProcessCpuTracker.getStats((st) -> {
16614 return st.vsize > 0;
16617 final int statsCount = stats.size();
16618 for (int i = 0; i < statsCount; i++) {
16619 ProcessCpuTracker.Stats st = stats.get(i);
16620 long pss = Debug.getPss(st.pid, null, memtrackTmp);
16622 if (infoMap.indexOfKey(st.pid) < 0) {
16623 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16624 ProcessList.NATIVE_ADJ, -1, "native", null);
16626 mi.memtrack = memtrackTmp[0];
16633 long totalMemtrack = 0;
16634 for (int i=0, N=memInfos.size(); i<N; i++) {
16635 ProcessMemInfo mi = memInfos.get(i);
16637 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16638 mi.memtrack = memtrackTmp[0];
16640 totalPss += mi.pss;
16641 totalMemtrack += mi.memtrack;
16643 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16644 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16645 if (lhs.oomAdj != rhs.oomAdj) {
16646 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16648 if (lhs.pss != rhs.pss) {
16649 return lhs.pss < rhs.pss ? 1 : -1;
16655 StringBuilder tag = new StringBuilder(128);
16656 StringBuilder stack = new StringBuilder(128);
16657 tag.append("Low on memory -- ");
16658 appendMemBucket(tag, totalPss, "total", false);
16659 appendMemBucket(stack, totalPss, "total", true);
16661 StringBuilder fullNativeBuilder = new StringBuilder(1024);
16662 StringBuilder shortNativeBuilder = new StringBuilder(1024);
16663 StringBuilder fullJavaBuilder = new StringBuilder(1024);
16665 boolean firstLine = true;
16666 int lastOomAdj = Integer.MIN_VALUE;
16667 long extraNativeRam = 0;
16668 long extraNativeMemtrack = 0;
16669 long cachedPss = 0;
16670 for (int i=0, N=memInfos.size(); i<N; i++) {
16671 ProcessMemInfo mi = memInfos.get(i);
16673 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16674 cachedPss += mi.pss;
16677 if (mi.oomAdj != ProcessList.NATIVE_ADJ
16678 && (mi.oomAdj < ProcessList.SERVICE_ADJ
16679 || mi.oomAdj == ProcessList.HOME_APP_ADJ
16680 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16681 if (lastOomAdj != mi.oomAdj) {
16682 lastOomAdj = mi.oomAdj;
16683 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16686 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16691 stack.append("\n\t at ");
16699 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16700 appendMemBucket(tag, mi.pss, mi.name, false);
16702 appendMemBucket(stack, mi.pss, mi.name, true);
16703 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16704 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16706 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16707 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16708 stack.append(DUMP_MEM_OOM_LABEL[k]);
16710 stack.append(DUMP_MEM_OOM_ADJ[k]);
16717 appendMemInfo(fullNativeBuilder, mi);
16718 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16719 // The short form only has native processes that are >= 512K.
16720 if (mi.pss >= 512) {
16721 appendMemInfo(shortNativeBuilder, mi);
16723 extraNativeRam += mi.pss;
16724 extraNativeMemtrack += mi.memtrack;
16727 // Short form has all other details, but if we have collected RAM
16728 // from smaller native processes let's dump a summary of that.
16729 if (extraNativeRam > 0) {
16730 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16731 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16732 shortNativeBuilder.append('\n');
16733 extraNativeRam = 0;
16735 appendMemInfo(fullJavaBuilder, mi);
16739 fullJavaBuilder.append(" ");
16740 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16741 fullJavaBuilder.append(": TOTAL");
16742 if (totalMemtrack > 0) {
16743 fullJavaBuilder.append(" (");
16744 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16745 fullJavaBuilder.append(" memtrack)");
16748 fullJavaBuilder.append("\n");
16750 MemInfoReader memInfo = new MemInfoReader();
16751 memInfo.readMemInfo();
16752 final long[] infos = memInfo.getRawInfo();
16754 StringBuilder memInfoBuilder = new StringBuilder(1024);
16755 Debug.getMemInfo(infos);
16756 memInfoBuilder.append(" MemInfo: ");
16757 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16758 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16759 memInfoBuilder.append(stringifyKBSize(
16760 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16761 memInfoBuilder.append(stringifyKBSize(
16762 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16763 memInfoBuilder.append(stringifyKBSize(
16764 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16765 memInfoBuilder.append(" ");
16766 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16767 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16768 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16769 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16770 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16771 memInfoBuilder.append(" ZRAM: ");
16772 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16773 memInfoBuilder.append(" RAM, ");
16774 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16775 memInfoBuilder.append(" swap total, ");
16776 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16777 memInfoBuilder.append(" swap free\n");
16779 final long[] ksm = getKsmInfo();
16780 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16781 || ksm[KSM_VOLATILE] != 0) {
16782 memInfoBuilder.append(" KSM: ");
16783 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16784 memInfoBuilder.append(" saved from shared ");
16785 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16786 memInfoBuilder.append("\n ");
16787 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16788 memInfoBuilder.append(" unshared; ");
16789 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16790 memInfoBuilder.append(" volatile\n");
16792 memInfoBuilder.append(" Free RAM: ");
16793 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16794 + memInfo.getFreeSizeKb()));
16795 memInfoBuilder.append("\n");
16796 memInfoBuilder.append(" Used RAM: ");
16797 memInfoBuilder.append(stringifyKBSize(
16798 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16799 memInfoBuilder.append("\n");
16800 memInfoBuilder.append(" Lost RAM: ");
16801 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16802 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16803 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16804 memInfoBuilder.append("\n");
16805 Slog.i(TAG, "Low on memory:");
16806 Slog.i(TAG, shortNativeBuilder.toString());
16807 Slog.i(TAG, fullJavaBuilder.toString());
16808 Slog.i(TAG, memInfoBuilder.toString());
16810 StringBuilder dropBuilder = new StringBuilder(1024);
16812 StringWriter oomSw = new StringWriter();
16813 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16814 StringWriter catSw = new StringWriter();
16815 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16816 String[] emptyArgs = new String[] { };
16817 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16819 String oomString = oomSw.toString();
16821 dropBuilder.append("Low on memory:");
16822 dropBuilder.append(stack);
16823 dropBuilder.append('\n');
16824 dropBuilder.append(fullNativeBuilder);
16825 dropBuilder.append(fullJavaBuilder);
16826 dropBuilder.append('\n');
16827 dropBuilder.append(memInfoBuilder);
16828 dropBuilder.append('\n');
16830 dropBuilder.append(oomString);
16831 dropBuilder.append('\n');
16833 StringWriter catSw = new StringWriter();
16834 synchronized (ActivityManagerService.this) {
16835 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16836 String[] emptyArgs = new String[] { };
16838 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16840 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16841 false, null).dumpLocked();
16843 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16846 dropBuilder.append(catSw.toString());
16847 addErrorToDropBox("lowmem", null, "system_server", null,
16848 null, tag.toString(), dropBuilder.toString(), null, null);
16849 //Slog.i(TAG, "Sent to dropbox:");
16850 //Slog.i(TAG, dropBuilder.toString());
16851 synchronized (ActivityManagerService.this) {
16852 long now = SystemClock.uptimeMillis();
16853 if (mLastMemUsageReportTime < now) {
16854 mLastMemUsageReportTime = now;
16860 * Searches array of arguments for the specified string
16861 * @param args array of argument strings
16862 * @param value value to search for
16863 * @return true if the value is contained in the array
16865 private static boolean scanArgs(String[] args, String value) {
16866 if (args != null) {
16867 for (String arg : args) {
16868 if (value.equals(arg)) {
16876 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16877 ContentProviderRecord cpr, boolean always) {
16878 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16880 if (!inLaunching || always) {
16881 synchronized (cpr) {
16882 cpr.launchingApp = null;
16885 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16886 String names[] = cpr.info.authority.split(";");
16887 for (int j = 0; j < names.length; j++) {
16888 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16892 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16893 ContentProviderConnection conn = cpr.connections.get(i);
16894 if (conn.waiting) {
16895 // If this connection is waiting for the provider, then we don't
16896 // need to mess with its process unless we are always removing
16897 // or for some reason the provider is not currently launching.
16898 if (inLaunching && !always) {
16902 ProcessRecord capp = conn.client;
16904 if (conn.stableCount > 0) {
16905 if (!capp.persistent && capp.thread != null
16907 && capp.pid != MY_PID) {
16908 capp.kill("depends on provider "
16909 + cpr.name.flattenToShortString()
16910 + " in dying proc " + (proc != null ? proc.processName : "??")
16911 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16913 } else if (capp.thread != null && conn.provider.provider != null) {
16915 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16916 } catch (RemoteException e) {
16918 // In the protocol here, we don't expect the client to correctly
16919 // clean up this connection, we'll just remove it.
16920 cpr.connections.remove(i);
16921 if (conn.client.conProviders.remove(conn)) {
16922 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16927 if (inLaunching && always) {
16928 mLaunchingProviders.remove(cpr);
16930 return inLaunching;
16934 * Main code for cleaning up a process when it has gone away. This is
16935 * called both as a result of the process dying, or directly when stopping
16936 * a process when running in single process mode.
16938 * @return Returns true if the given process has been restarted, so the
16939 * app that was passed in must remain on the process lists.
16941 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16942 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16943 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16945 removeLruProcessLocked(app);
16946 ProcessList.remove(app.pid);
16949 mProcessesToGc.remove(app);
16950 mPendingPssProcesses.remove(app);
16952 // Dismiss any open dialogs.
16953 if (app.crashDialog != null && !app.forceCrashReport) {
16954 app.crashDialog.dismiss();
16955 app.crashDialog = null;
16957 if (app.anrDialog != null) {
16958 app.anrDialog.dismiss();
16959 app.anrDialog = null;
16961 if (app.waitDialog != null) {
16962 app.waitDialog.dismiss();
16963 app.waitDialog = null;
16966 app.crashing = false;
16967 app.notResponding = false;
16969 app.resetPackageList(mProcessStats);
16970 app.unlinkDeathRecipient();
16971 app.makeInactive(mProcessStats);
16972 app.waitingToKill = null;
16973 app.forcingToForeground = null;
16974 updateProcessForegroundLocked(app, false, false);
16975 app.foregroundActivities = false;
16976 app.hasShownUi = false;
16977 app.treatLikeActivity = false;
16978 app.hasAboveClient = false;
16979 app.hasClientActivities = false;
16981 mServices.killServicesLocked(app, allowRestart);
16983 boolean restart = false;
16985 // Remove published content providers.
16986 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16987 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16988 final boolean always = app.bad || !allowRestart;
16989 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16990 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16991 // We left the provider in the launching list, need to
16996 cpr.provider = null;
16999 app.pubProviders.clear();
17001 // Take care of any launching providers waiting for this process.
17002 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17006 // Unregister from connected content providers.
17007 if (!app.conProviders.isEmpty()) {
17008 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17009 ContentProviderConnection conn = app.conProviders.get(i);
17010 conn.provider.connections.remove(conn);
17011 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17012 conn.provider.name);
17014 app.conProviders.clear();
17017 // At this point there may be remaining entries in mLaunchingProviders
17018 // where we were the only one waiting, so they are no longer of use.
17019 // Look for these and clean up if found.
17020 // XXX Commented out for now. Trying to figure out a way to reproduce
17021 // the actual situation to identify what is actually going on.
17023 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17024 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17025 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17026 synchronized (cpr) {
17027 cpr.launchingApp = null;
17034 skipCurrentReceiverLocked(app);
17036 // Unregister any receivers.
17037 for (int i = app.receivers.size() - 1; i >= 0; i--) {
17038 removeReceiverLocked(app.receivers.valueAt(i));
17040 app.receivers.clear();
17042 // If the app is undergoing backup, tell the backup manager about it
17043 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17044 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17045 + mBackupTarget.appInfo + " died during backup");
17047 IBackupManager bm = IBackupManager.Stub.asInterface(
17048 ServiceManager.getService(Context.BACKUP_SERVICE));
17049 bm.agentDisconnected(app.info.packageName);
17050 } catch (RemoteException e) {
17051 // can't happen; backup manager is local
17055 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17056 ProcessChangeItem item = mPendingProcessChanges.get(i);
17057 if (item.pid == app.pid) {
17058 mPendingProcessChanges.remove(i);
17059 mAvailProcessChanges.add(item);
17062 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17063 null).sendToTarget();
17065 // If the caller is restarting this app, then leave it in its
17066 // current lists and let the caller take care of it.
17071 if (!app.persistent || app.isolated) {
17072 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17073 "Removing non-persistent process during cleanup: " + app);
17074 if (!replacingPid) {
17075 removeProcessNameLocked(app.processName, app.uid, app);
17077 if (mHeavyWeightProcess == app) {
17078 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17079 mHeavyWeightProcess.userId, 0));
17080 mHeavyWeightProcess = null;
17082 } else if (!app.removed) {
17083 // This app is persistent, so we need to keep its record around.
17084 // If it is not already on the pending app list, add it there
17085 // and start a new process for it.
17086 if (mPersistentStartingProcesses.indexOf(app) < 0) {
17087 mPersistentStartingProcesses.add(app);
17091 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17092 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17093 mProcessesOnHold.remove(app);
17095 if (app == mHomeProcess) {
17096 mHomeProcess = null;
17098 if (app == mPreviousProcess) {
17099 mPreviousProcess = null;
17102 if (restart && !app.isolated) {
17103 // We have components that still need to be running in the
17104 // process, so re-launch it.
17106 ProcessList.remove(app.pid);
17108 addProcessNameLocked(app);
17109 startProcessLocked(app, "restart", app.processName);
17111 } else if (app.pid > 0 && app.pid != MY_PID) {
17114 synchronized (mPidsSelfLocked) {
17115 mPidsSelfLocked.remove(app.pid);
17116 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17118 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17119 if (app.isolated) {
17120 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17127 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17128 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17129 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17130 if (cpr.launchingApp == app) {
17137 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17138 // Look through the content providers we are waiting to have launched,
17139 // and if any run in this process then either schedule a restart of
17140 // the process or kill the client waiting for it if this process has
17142 boolean restart = false;
17143 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17144 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17145 if (cpr.launchingApp == app) {
17146 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17149 removeDyingProviderLocked(app, cpr, true);
17156 // =========================================================
17158 // =========================================================
17161 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17163 enforceNotIsolatedCaller("getServices");
17164 synchronized (this) {
17165 return mServices.getRunningServiceInfoLocked(maxNum, flags);
17170 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17171 enforceNotIsolatedCaller("getRunningServiceControlPanel");
17172 synchronized (this) {
17173 return mServices.getRunningServiceControlPanelLocked(name);
17178 public ComponentName startService(IApplicationThread caller, Intent service,
17179 String resolvedType, String callingPackage, int userId)
17180 throws TransactionTooLargeException {
17181 enforceNotIsolatedCaller("startService");
17182 // Refuse possible leaked file descriptors
17183 if (service != null && service.hasFileDescriptors() == true) {
17184 throw new IllegalArgumentException("File descriptors passed in Intent");
17187 if (callingPackage == null) {
17188 throw new IllegalArgumentException("callingPackage cannot be null");
17191 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17192 "startService: " + service + " type=" + resolvedType);
17193 synchronized(this) {
17194 final int callingPid = Binder.getCallingPid();
17195 final int callingUid = Binder.getCallingUid();
17196 final long origId = Binder.clearCallingIdentity();
17197 ComponentName res = mServices.startServiceLocked(caller, service,
17198 resolvedType, callingPid, callingUid, callingPackage, userId);
17199 Binder.restoreCallingIdentity(origId);
17204 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17205 String callingPackage, int userId)
17206 throws TransactionTooLargeException {
17207 synchronized(this) {
17208 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17209 "startServiceInPackage: " + service + " type=" + resolvedType);
17210 final long origId = Binder.clearCallingIdentity();
17211 ComponentName res = mServices.startServiceLocked(null, service,
17212 resolvedType, -1, uid, callingPackage, userId);
17213 Binder.restoreCallingIdentity(origId);
17219 public int stopService(IApplicationThread caller, Intent service,
17220 String resolvedType, int userId) {
17221 enforceNotIsolatedCaller("stopService");
17222 // Refuse possible leaked file descriptors
17223 if (service != null && service.hasFileDescriptors() == true) {
17224 throw new IllegalArgumentException("File descriptors passed in Intent");
17227 synchronized(this) {
17228 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17233 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17234 enforceNotIsolatedCaller("peekService");
17235 // Refuse possible leaked file descriptors
17236 if (service != null && service.hasFileDescriptors() == true) {
17237 throw new IllegalArgumentException("File descriptors passed in Intent");
17240 if (callingPackage == null) {
17241 throw new IllegalArgumentException("callingPackage cannot be null");
17244 synchronized(this) {
17245 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17250 public boolean stopServiceToken(ComponentName className, IBinder token,
17252 synchronized(this) {
17253 return mServices.stopServiceTokenLocked(className, token, startId);
17258 public void setServiceForeground(ComponentName className, IBinder token,
17259 int id, Notification notification, int flags) {
17260 synchronized(this) {
17261 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17266 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17267 boolean requireFull, String name, String callerPackage) {
17268 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17269 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17272 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17273 String className, int flags) {
17274 boolean result = false;
17275 // For apps that don't have pre-defined UIDs, check for permission
17276 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17277 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17278 if (ActivityManager.checkUidPermission(
17279 INTERACT_ACROSS_USERS,
17280 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17281 ComponentName comp = new ComponentName(aInfo.packageName, className);
17282 String msg = "Permission Denial: Component " + comp.flattenToShortString()
17283 + " requests FLAG_SINGLE_USER, but app does not hold "
17284 + INTERACT_ACROSS_USERS;
17286 throw new SecurityException(msg);
17288 // Permission passed
17291 } else if ("system".equals(componentProcessName)) {
17293 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17294 // Phone app and persistent apps are allowed to export singleuser providers.
17295 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17296 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17298 if (DEBUG_MU) Slog.v(TAG_MU,
17299 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17300 + Integer.toHexString(flags) + ") = " + result);
17305 * Checks to see if the caller is in the same app as the singleton
17306 * component, or the component is in a special app. It allows special apps
17307 * to export singleton components but prevents exporting singleton
17308 * components for regular apps.
17310 boolean isValidSingletonCall(int callingUid, int componentUid) {
17311 int componentAppId = UserHandle.getAppId(componentUid);
17312 return UserHandle.isSameApp(callingUid, componentUid)
17313 || componentAppId == Process.SYSTEM_UID
17314 || componentAppId == Process.PHONE_UID
17315 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17316 == PackageManager.PERMISSION_GRANTED;
17319 public int bindService(IApplicationThread caller, IBinder token, Intent service,
17320 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17321 int userId) throws TransactionTooLargeException {
17322 enforceNotIsolatedCaller("bindService");
17324 // Refuse possible leaked file descriptors
17325 if (service != null && service.hasFileDescriptors() == true) {
17326 throw new IllegalArgumentException("File descriptors passed in Intent");
17329 if (callingPackage == null) {
17330 throw new IllegalArgumentException("callingPackage cannot be null");
17333 synchronized(this) {
17334 return mServices.bindServiceLocked(caller, token, service,
17335 resolvedType, connection, flags, callingPackage, userId);
17339 public boolean unbindService(IServiceConnection connection) {
17340 synchronized (this) {
17341 return mServices.unbindServiceLocked(connection);
17345 public void publishService(IBinder token, Intent intent, IBinder service) {
17346 // Refuse possible leaked file descriptors
17347 if (intent != null && intent.hasFileDescriptors() == true) {
17348 throw new IllegalArgumentException("File descriptors passed in Intent");
17351 synchronized(this) {
17352 if (!(token instanceof ServiceRecord)) {
17353 throw new IllegalArgumentException("Invalid service token");
17355 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17359 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17360 // Refuse possible leaked file descriptors
17361 if (intent != null && intent.hasFileDescriptors() == true) {
17362 throw new IllegalArgumentException("File descriptors passed in Intent");
17365 synchronized(this) {
17366 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17370 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17371 synchronized(this) {
17372 if (!(token instanceof ServiceRecord)) {
17373 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17374 throw new IllegalArgumentException("Invalid service token");
17376 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17380 // =========================================================
17381 // BACKUP AND RESTORE
17382 // =========================================================
17384 // Cause the target app to be launched if necessary and its backup agent
17385 // instantiated. The backup agent will invoke backupAgentCreated() on the
17386 // activity manager to announce its creation.
17387 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17388 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17389 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17391 IPackageManager pm = AppGlobals.getPackageManager();
17392 ApplicationInfo app = null;
17394 app = pm.getApplicationInfo(packageName, 0, userId);
17395 } catch (RemoteException e) {
17396 // can't happen; package manager is process-local
17399 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17403 synchronized(this) {
17404 // !!! TODO: currently no check here that we're already bound
17405 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17406 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17407 synchronized (stats) {
17408 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17411 // Backup agent is now in use, its package can't be stopped.
17413 AppGlobals.getPackageManager().setPackageStoppedState(
17414 app.packageName, false, UserHandle.getUserId(app.uid));
17415 } catch (RemoteException e) {
17416 } catch (IllegalArgumentException e) {
17417 Slog.w(TAG, "Failed trying to unstop package "
17418 + app.packageName + ": " + e);
17421 BackupRecord r = new BackupRecord(ss, app, backupMode);
17422 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17423 ? new ComponentName(app.packageName, app.backupAgentName)
17424 : new ComponentName("android", "FullBackupAgent");
17425 // startProcessLocked() returns existing proc's record if it's already running
17426 ProcessRecord proc = startProcessLocked(app.processName, app,
17427 false, 0, "backup", hostingName, false, false, false);
17428 if (proc == null) {
17429 Slog.e(TAG, "Unable to start backup agent process " + r);
17433 // If the app is a regular app (uid >= 10000) and not the system server or phone
17434 // process, etc, then mark it as being in full backup so that certain calls to the
17435 // process can be blocked. This is not reset to false anywhere because we kill the
17436 // process after the full backup is done and the ProcessRecord will vaporize anyway.
17437 if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17438 proc.inFullBackup = true;
17442 mBackupAppName = app.packageName;
17444 // Try not to kill the process during backup
17445 updateOomAdjLocked(proc);
17447 // If the process is already attached, schedule the creation of the backup agent now.
17448 // If it is not yet live, this will be done when it attaches to the framework.
17449 if (proc.thread != null) {
17450 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17452 proc.thread.scheduleCreateBackupAgent(app,
17453 compatibilityInfoForPackageLocked(app), backupMode);
17454 } catch (RemoteException e) {
17455 // Will time out on the backup manager side
17458 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17460 // Invariants: at this point, the target app process exists and the application
17461 // is either already running or in the process of coming up. mBackupTarget and
17462 // mBackupAppName describe the app, so that when it binds back to the AM we
17463 // know that it's scheduled for a backup-agent operation.
17470 public void clearPendingBackup() {
17471 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17472 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17474 synchronized (this) {
17475 mBackupTarget = null;
17476 mBackupAppName = null;
17480 // A backup agent has just come up
17481 public void backupAgentCreated(String agentPackageName, IBinder agent) {
17482 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17485 synchronized(this) {
17486 if (!agentPackageName.equals(mBackupAppName)) {
17487 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17492 long oldIdent = Binder.clearCallingIdentity();
17494 IBackupManager bm = IBackupManager.Stub.asInterface(
17495 ServiceManager.getService(Context.BACKUP_SERVICE));
17496 bm.agentConnected(agentPackageName, agent);
17497 } catch (RemoteException e) {
17498 // can't happen; the backup manager service is local
17499 } catch (Exception e) {
17500 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17501 e.printStackTrace();
17503 Binder.restoreCallingIdentity(oldIdent);
17507 // done with this agent
17508 public void unbindBackupAgent(ApplicationInfo appInfo) {
17509 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17510 if (appInfo == null) {
17511 Slog.w(TAG, "unbind backup agent for null app");
17515 synchronized(this) {
17517 if (mBackupAppName == null) {
17518 Slog.w(TAG, "Unbinding backup agent with no active backup");
17522 if (!mBackupAppName.equals(appInfo.packageName)) {
17523 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17527 // Not backing this app up any more; reset its OOM adjustment
17528 final ProcessRecord proc = mBackupTarget.app;
17529 updateOomAdjLocked(proc);
17531 // If the app crashed during backup, 'thread' will be null here
17532 if (proc.thread != null) {
17534 proc.thread.scheduleDestroyBackupAgent(appInfo,
17535 compatibilityInfoForPackageLocked(appInfo));
17536 } catch (Exception e) {
17537 Slog.e(TAG, "Exception when unbinding backup agent:");
17538 e.printStackTrace();
17542 mBackupTarget = null;
17543 mBackupAppName = null;
17547 // =========================================================
17549 // =========================================================
17551 boolean isPendingBroadcastProcessLocked(int pid) {
17552 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17553 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17556 void skipPendingBroadcastLocked(int pid) {
17557 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17558 for (BroadcastQueue queue : mBroadcastQueues) {
17559 queue.skipPendingBroadcastLocked(pid);
17563 // The app just attached; send any pending broadcasts that it should receive
17564 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17565 boolean didSomething = false;
17566 for (BroadcastQueue queue : mBroadcastQueues) {
17567 didSomething |= queue.sendPendingBroadcastsLocked(app);
17569 return didSomething;
17572 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17573 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17574 enforceNotIsolatedCaller("registerReceiver");
17575 ArrayList<Intent> stickyIntents = null;
17576 ProcessRecord callerApp = null;
17579 synchronized(this) {
17580 if (caller != null) {
17581 callerApp = getRecordForAppLocked(caller);
17582 if (callerApp == null) {
17583 throw new SecurityException(
17584 "Unable to find app for caller " + caller
17585 + " (pid=" + Binder.getCallingPid()
17586 + ") when registering receiver " + receiver);
17588 if (callerApp.info.uid != Process.SYSTEM_UID &&
17589 !callerApp.pkgList.containsKey(callerPackage) &&
17590 !"android".equals(callerPackage)) {
17591 throw new SecurityException("Given caller package " + callerPackage
17592 + " is not running in process " + callerApp);
17594 callingUid = callerApp.info.uid;
17595 callingPid = callerApp.pid;
17597 callerPackage = null;
17598 callingUid = Binder.getCallingUid();
17599 callingPid = Binder.getCallingPid();
17602 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17603 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17605 Iterator<String> actions = filter.actionsIterator();
17606 if (actions == null) {
17607 ArrayList<String> noAction = new ArrayList<String>(1);
17608 noAction.add(null);
17609 actions = noAction.iterator();
17612 // Collect stickies of users
17613 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17614 while (actions.hasNext()) {
17615 String action = actions.next();
17616 for (int id : userIds) {
17617 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17618 if (stickies != null) {
17619 ArrayList<Intent> intents = stickies.get(action);
17620 if (intents != null) {
17621 if (stickyIntents == null) {
17622 stickyIntents = new ArrayList<Intent>();
17624 stickyIntents.addAll(intents);
17631 ArrayList<Intent> allSticky = null;
17632 if (stickyIntents != null) {
17633 final ContentResolver resolver = mContext.getContentResolver();
17634 // Look for any matching sticky broadcasts...
17635 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17636 Intent intent = stickyIntents.get(i);
17637 // If intent has scheme "content", it will need to acccess
17638 // provider that needs to lock mProviderMap in ActivityThread
17639 // and also it may need to wait application response, so we
17640 // cannot lock ActivityManagerService here.
17641 if (filter.match(resolver, intent, true, TAG) >= 0) {
17642 if (allSticky == null) {
17643 allSticky = new ArrayList<Intent>();
17645 allSticky.add(intent);
17650 // The first sticky in the list is returned directly back to the client.
17651 Intent sticky = allSticky != null ? allSticky.get(0) : null;
17652 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17653 if (receiver == null) {
17657 synchronized (this) {
17658 if (callerApp != null && (callerApp.thread == null
17659 || callerApp.thread.asBinder() != caller.asBinder())) {
17660 // Original caller already died
17663 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17665 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17667 if (rl.app != null) {
17668 rl.app.receivers.add(rl);
17671 receiver.asBinder().linkToDeath(rl, 0);
17672 } catch (RemoteException e) {
17675 rl.linkedToDeath = true;
17677 mRegisteredReceivers.put(receiver.asBinder(), rl);
17678 } else if (rl.uid != callingUid) {
17679 throw new IllegalArgumentException(
17680 "Receiver requested to register for uid " + callingUid
17681 + " was previously registered for uid " + rl.uid);
17682 } else if (rl.pid != callingPid) {
17683 throw new IllegalArgumentException(
17684 "Receiver requested to register for pid " + callingPid
17685 + " was previously registered for pid " + rl.pid);
17686 } else if (rl.userId != userId) {
17687 throw new IllegalArgumentException(
17688 "Receiver requested to register for user " + userId
17689 + " was previously registered for user " + rl.userId);
17691 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17692 permission, callingUid, userId);
17694 if (!bf.debugCheck()) {
17695 Slog.w(TAG, "==> For Dynamic broadcast");
17697 mReceiverResolver.addFilter(bf);
17699 // Enqueue broadcasts for all existing stickies that match
17701 if (allSticky != null) {
17702 ArrayList receivers = new ArrayList();
17705 final int stickyCount = allSticky.size();
17706 for (int i = 0; i < stickyCount; i++) {
17707 Intent intent = allSticky.get(i);
17708 BroadcastQueue queue = broadcastQueueForIntent(intent);
17709 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17710 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17711 null, 0, null, null, false, true, true, -1);
17712 queue.enqueueParallelBroadcastLocked(r);
17713 queue.scheduleBroadcastsLocked();
17721 public void unregisterReceiver(IIntentReceiver receiver) {
17722 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17724 final long origId = Binder.clearCallingIdentity();
17726 boolean doTrim = false;
17728 synchronized(this) {
17729 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17731 final BroadcastRecord r = rl.curBroadcast;
17732 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17733 final boolean doNext = r.queue.finishReceiverLocked(
17734 r, r.resultCode, r.resultData, r.resultExtras,
17735 r.resultAbort, false);
17738 r.queue.processNextBroadcast(false);
17742 if (rl.app != null) {
17743 rl.app.receivers.remove(rl);
17745 removeReceiverLocked(rl);
17746 if (rl.linkedToDeath) {
17747 rl.linkedToDeath = false;
17748 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17753 // If we actually concluded any broadcasts, we might now be able
17754 // to trim the recipients' apps from our working set
17756 trimApplications();
17761 Binder.restoreCallingIdentity(origId);
17765 void removeReceiverLocked(ReceiverList rl) {
17766 mRegisteredReceivers.remove(rl.receiver.asBinder());
17767 for (int i = rl.size() - 1; i >= 0; i--) {
17768 mReceiverResolver.removeFilter(rl.get(i));
17772 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17773 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17774 ProcessRecord r = mLruProcesses.get(i);
17775 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17777 r.thread.dispatchPackageBroadcast(cmd, packages);
17778 } catch (RemoteException ex) {
17784 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17785 int callingUid, int[] users) {
17786 // TODO: come back and remove this assumption to triage all broadcasts
17787 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17789 List<ResolveInfo> receivers = null;
17791 HashSet<ComponentName> singleUserReceivers = null;
17792 boolean scannedFirstReceivers = false;
17793 for (int user : users) {
17794 // Skip users that have Shell restrictions, with exception of always permitted
17795 // Shell broadcasts
17796 if (callingUid == Process.SHELL_UID
17797 && mUserController.hasUserRestriction(
17798 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17799 && !isPermittedShellBroadcast(intent)) {
17802 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17803 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17804 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17805 // If this is not the system user, we need to check for
17806 // any receivers that should be filtered out.
17807 for (int i=0; i<newReceivers.size(); i++) {
17808 ResolveInfo ri = newReceivers.get(i);
17809 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17810 newReceivers.remove(i);
17815 if (newReceivers != null && newReceivers.size() == 0) {
17816 newReceivers = null;
17818 if (receivers == null) {
17819 receivers = newReceivers;
17820 } else if (newReceivers != null) {
17821 // We need to concatenate the additional receivers
17822 // found with what we have do far. This would be easy,
17823 // but we also need to de-dup any receivers that are
17825 if (!scannedFirstReceivers) {
17826 // Collect any single user receivers we had already retrieved.
17827 scannedFirstReceivers = true;
17828 for (int i=0; i<receivers.size(); i++) {
17829 ResolveInfo ri = receivers.get(i);
17830 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17831 ComponentName cn = new ComponentName(
17832 ri.activityInfo.packageName, ri.activityInfo.name);
17833 if (singleUserReceivers == null) {
17834 singleUserReceivers = new HashSet<ComponentName>();
17836 singleUserReceivers.add(cn);
17840 // Add the new results to the existing results, tracking
17841 // and de-dupping single user receivers.
17842 for (int i=0; i<newReceivers.size(); i++) {
17843 ResolveInfo ri = newReceivers.get(i);
17844 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17845 ComponentName cn = new ComponentName(
17846 ri.activityInfo.packageName, ri.activityInfo.name);
17847 if (singleUserReceivers == null) {
17848 singleUserReceivers = new HashSet<ComponentName>();
17850 if (!singleUserReceivers.contains(cn)) {
17851 singleUserReceivers.add(cn);
17860 } catch (RemoteException ex) {
17861 // pm is in same process, this will never happen.
17866 private boolean isPermittedShellBroadcast(Intent intent) {
17867 // remote bugreport should always be allowed to be taken
17868 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17871 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17872 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17873 final String action = intent.getAction();
17874 if (isProtectedBroadcast
17875 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17876 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17877 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17878 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17879 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17880 || Intent.ACTION_MASTER_CLEAR.equals(action)
17881 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17882 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17883 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17884 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17885 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17886 // Broadcast is either protected, or it's a public action that
17887 // we've relaxed, so it's fine for system internals to send.
17891 // This broadcast may be a problem... but there are often system components that
17892 // want to send an internal broadcast to themselves, which is annoying to have to
17893 // explicitly list each action as a protected broadcast, so we will check for that
17894 // one safe case and allow it: an explicit broadcast, only being received by something
17895 // that has protected itself.
17896 if (receivers != null && receivers.size() > 0
17897 && (intent.getPackage() != null || intent.getComponent() != null)) {
17898 boolean allProtected = true;
17899 for (int i = receivers.size()-1; i >= 0; i--) {
17900 Object target = receivers.get(i);
17901 if (target instanceof ResolveInfo) {
17902 ResolveInfo ri = (ResolveInfo)target;
17903 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17904 allProtected = false;
17908 BroadcastFilter bf = (BroadcastFilter)target;
17909 if (bf.requiredPermission == null) {
17910 allProtected = false;
17915 if (allProtected) {
17921 // The vast majority of broadcasts sent from system internals
17922 // should be protected to avoid security holes, so yell loudly
17923 // to ensure we examine these cases.
17924 if (callerApp != null) {
17925 Log.wtf(TAG, "Sending non-protected broadcast " + action
17926 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17929 Log.wtf(TAG, "Sending non-protected broadcast " + action
17930 + " from system uid " + UserHandle.formatUid(callingUid)
17931 + " pkg " + callerPackage,
17936 final int broadcastIntentLocked(ProcessRecord callerApp,
17937 String callerPackage, Intent intent, String resolvedType,
17938 IIntentReceiver resultTo, int resultCode, String resultData,
17939 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17940 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17941 intent = new Intent(intent);
17943 // By default broadcasts do not go to stopped apps.
17944 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17946 // If we have not finished booting, don't allow this to launch new processes.
17947 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17948 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17951 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17952 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17953 + " ordered=" + ordered + " userid=" + userId);
17954 if ((resultTo != null) && !ordered) {
17955 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17958 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17959 ALLOW_NON_FULL, "broadcast", callerPackage);
17961 // Make sure that the user who is receiving this broadcast is running.
17962 // If not, we will just skip it. Make an exception for shutdown broadcasts
17963 // and upgrade steps.
17965 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17966 if ((callingUid != Process.SYSTEM_UID
17967 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17968 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17969 Slog.w(TAG, "Skipping broadcast of " + intent
17970 + ": user " + userId + " is stopped");
17971 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17975 BroadcastOptions brOptions = null;
17976 if (bOptions != null) {
17977 brOptions = new BroadcastOptions(bOptions);
17978 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17979 // See if the caller is allowed to do this. Note we are checking against
17980 // the actual real caller (not whoever provided the operation as say a
17981 // PendingIntent), because that who is actually supplied the arguments.
17982 if (checkComponentPermission(
17983 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17984 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17985 != PackageManager.PERMISSION_GRANTED) {
17986 String msg = "Permission Denial: " + intent.getAction()
17987 + " broadcast from " + callerPackage + " (pid=" + callingPid
17988 + ", uid=" + callingUid + ")"
17990 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17992 throw new SecurityException(msg);
17997 // Verify that protected broadcasts are only being sent by system code,
17998 // and that system code is only sending protected broadcasts.
17999 final String action = intent.getAction();
18000 final boolean isProtectedBroadcast;
18002 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18003 } catch (RemoteException e) {
18004 Slog.w(TAG, "Remote exception", e);
18005 return ActivityManager.BROADCAST_SUCCESS;
18008 final boolean isCallerSystem;
18009 switch (UserHandle.getAppId(callingUid)) {
18010 case Process.ROOT_UID:
18011 case Process.SYSTEM_UID:
18012 case Process.PHONE_UID:
18013 case Process.BLUETOOTH_UID:
18014 case Process.NFC_UID:
18015 isCallerSystem = true;
18018 isCallerSystem = (callerApp != null) && callerApp.persistent;
18022 // First line security check before anything else: stop non-system apps from
18023 // sending protected broadcasts.
18024 if (!isCallerSystem) {
18025 if (isProtectedBroadcast) {
18026 String msg = "Permission Denial: not allowed to send broadcast "
18027 + action + " from pid="
18028 + callingPid + ", uid=" + callingUid;
18030 throw new SecurityException(msg);
18032 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18033 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18034 // Special case for compatibility: we don't want apps to send this,
18035 // but historically it has not been protected and apps may be using it
18036 // to poke their own app widget. So, instead of making it protected,
18037 // just limit it to the caller.
18038 if (callerPackage == null) {
18039 String msg = "Permission Denial: not allowed to send broadcast "
18040 + action + " from unknown caller.";
18042 throw new SecurityException(msg);
18043 } else if (intent.getComponent() != null) {
18044 // They are good enough to send to an explicit component... verify
18045 // it is being sent to the calling app.
18046 if (!intent.getComponent().getPackageName().equals(
18048 String msg = "Permission Denial: not allowed to send broadcast "
18050 + intent.getComponent().getPackageName() + " from "
18053 throw new SecurityException(msg);
18056 // Limit broadcast to their own package.
18057 intent.setPackage(callerPackage);
18062 if (action != null) {
18064 case Intent.ACTION_UID_REMOVED:
18065 case Intent.ACTION_PACKAGE_REMOVED:
18066 case Intent.ACTION_PACKAGE_CHANGED:
18067 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18068 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18069 case Intent.ACTION_PACKAGES_SUSPENDED:
18070 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18071 // Handle special intents: if this broadcast is from the package
18072 // manager about a package being removed, we need to remove all of
18073 // its activities from the history stack.
18074 if (checkComponentPermission(
18075 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18076 callingPid, callingUid, -1, true)
18077 != PackageManager.PERMISSION_GRANTED) {
18078 String msg = "Permission Denial: " + intent.getAction()
18079 + " broadcast from " + callerPackage + " (pid=" + callingPid
18080 + ", uid=" + callingUid + ")"
18082 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18084 throw new SecurityException(msg);
18087 case Intent.ACTION_UID_REMOVED:
18088 final Bundle intentExtras = intent.getExtras();
18089 final int uid = intentExtras != null
18090 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18092 mBatteryStatsService.removeUid(uid);
18093 mAppOpsService.uidRemoved(uid);
18096 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18097 // If resources are unavailable just force stop all those packages
18098 // and flush the attribute cache as well.
18100 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18101 if (list != null && list.length > 0) {
18102 for (int i = 0; i < list.length; i++) {
18103 forceStopPackageLocked(list[i], -1, false, true, true,
18104 false, false, userId, "storage unmount");
18106 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18107 sendPackageBroadcastLocked(
18108 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18112 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18113 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18115 case Intent.ACTION_PACKAGE_REMOVED:
18116 case Intent.ACTION_PACKAGE_CHANGED:
18117 Uri data = intent.getData();
18119 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18120 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18121 final boolean replacing =
18122 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18123 final boolean killProcess =
18124 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18125 final boolean fullUninstall = removed && !replacing;
18128 forceStopPackageLocked(ssp, UserHandle.getAppId(
18129 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18130 false, true, true, false, fullUninstall, userId,
18131 removed ? "pkg removed" : "pkg changed");
18133 final int cmd = killProcess
18134 ? IApplicationThread.PACKAGE_REMOVED
18135 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18136 sendPackageBroadcastLocked(cmd,
18137 new String[] {ssp}, userId);
18138 if (fullUninstall) {
18139 mAppOpsService.packageRemoved(
18140 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18142 // Remove all permissions granted from/to this package
18143 removeUriPermissionsForPackageLocked(ssp, userId, true);
18145 removeTasksByPackageNameLocked(ssp, userId);
18147 // Hide the "unsupported display" dialog if necessary.
18148 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18149 mUnsupportedDisplaySizeDialog.getPackageName())) {
18150 mUnsupportedDisplaySizeDialog.dismiss();
18151 mUnsupportedDisplaySizeDialog = null;
18153 mCompatModePackages.handlePackageUninstalledLocked(ssp);
18154 mBatteryStatsService.notePackageUninstalled(ssp);
18158 killPackageProcessesLocked(ssp, UserHandle.getAppId(
18159 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18160 userId, ProcessList.INVALID_ADJ,
18161 false, true, true, false, "change " + ssp);
18163 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18164 intent.getStringArrayExtra(
18165 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18169 case Intent.ACTION_PACKAGES_SUSPENDED:
18170 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18171 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18172 intent.getAction());
18173 final String[] packageNames = intent.getStringArrayExtra(
18174 Intent.EXTRA_CHANGED_PACKAGE_LIST);
18175 final int userHandle = intent.getIntExtra(
18176 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18178 synchronized(ActivityManagerService.this) {
18179 mRecentTasks.onPackagesSuspendedChanged(
18180 packageNames, suspended, userHandle);
18185 case Intent.ACTION_PACKAGE_REPLACED:
18187 final Uri data = intent.getData();
18189 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18190 final ApplicationInfo aInfo =
18191 getPackageManagerInternalLocked().getApplicationInfo(
18194 if (aInfo == null) {
18195 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18196 + " ssp=" + ssp + " data=" + data);
18197 return ActivityManager.BROADCAST_SUCCESS;
18199 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18200 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18201 new String[] {ssp}, userId);
18205 case Intent.ACTION_PACKAGE_ADDED:
18207 // Special case for adding a package: by default turn on compatibility mode.
18208 Uri data = intent.getData();
18210 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18211 final boolean replacing =
18212 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18213 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18216 ApplicationInfo ai = AppGlobals.getPackageManager().
18217 getApplicationInfo(ssp, 0, 0);
18218 mBatteryStatsService.notePackageInstalled(ssp,
18219 ai != null ? ai.versionCode : 0);
18220 } catch (RemoteException e) {
18225 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18227 Uri data = intent.getData();
18229 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18230 // Hide the "unsupported display" dialog if necessary.
18231 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18232 mUnsupportedDisplaySizeDialog.getPackageName())) {
18233 mUnsupportedDisplaySizeDialog.dismiss();
18234 mUnsupportedDisplaySizeDialog = null;
18236 mCompatModePackages.handlePackageDataClearedLocked(ssp);
18240 case Intent.ACTION_TIMEZONE_CHANGED:
18241 // If this is the time zone changed action, queue up a message that will reset
18242 // the timezone of all currently running processes. This message will get
18243 // queued up before the broadcast happens.
18244 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18246 case Intent.ACTION_TIME_CHANGED:
18247 // If the user set the time, let all running processes know.
18248 final int is24Hour =
18249 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18251 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18252 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18253 synchronized (stats) {
18254 stats.noteCurrentTimeChangedLocked();
18257 case Intent.ACTION_CLEAR_DNS_CACHE:
18258 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18260 case Proxy.PROXY_CHANGE_ACTION:
18261 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18262 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18264 case android.hardware.Camera.ACTION_NEW_PICTURE:
18265 case android.hardware.Camera.ACTION_NEW_VIDEO:
18266 // These broadcasts are no longer allowed by the system, since they can
18267 // cause significant thrashing at a crictical point (using the camera).
18268 // Apps should use JobScehduler to monitor for media provider changes.
18269 Slog.w(TAG, action + " no longer allowed; dropping from "
18270 + UserHandle.formatUid(callingUid));
18271 if (resultTo != null) {
18272 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18274 queue.performReceiveLocked(callerApp, resultTo, intent,
18275 Activity.RESULT_CANCELED, null, null,
18276 false, false, userId);
18277 } catch (RemoteException e) {
18278 Slog.w(TAG, "Failure ["
18279 + queue.mQueueName + "] sending broadcast result of "
18284 // Lie; we don't want to crash the app.
18285 return ActivityManager.BROADCAST_SUCCESS;
18289 // Add to the sticky list if requested.
18291 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18292 callingPid, callingUid)
18293 != PackageManager.PERMISSION_GRANTED) {
18294 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18295 + callingPid + ", uid=" + callingUid
18296 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18298 throw new SecurityException(msg);
18300 if (requiredPermissions != null && requiredPermissions.length > 0) {
18301 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18302 + " and enforce permissions " + Arrays.toString(requiredPermissions));
18303 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18305 if (intent.getComponent() != null) {
18306 throw new SecurityException(
18307 "Sticky broadcasts can't target a specific component");
18309 // We use userId directly here, since the "all" target is maintained
18310 // as a separate set of sticky broadcasts.
18311 if (userId != UserHandle.USER_ALL) {
18312 // But first, if this is not a broadcast to all users, then
18313 // make sure it doesn't conflict with an existing broadcast to
18315 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18316 UserHandle.USER_ALL);
18317 if (stickies != null) {
18318 ArrayList<Intent> list = stickies.get(intent.getAction());
18319 if (list != null) {
18320 int N = list.size();
18322 for (i=0; i<N; i++) {
18323 if (intent.filterEquals(list.get(i))) {
18324 throw new IllegalArgumentException(
18325 "Sticky broadcast " + intent + " for user "
18326 + userId + " conflicts with existing global broadcast");
18332 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18333 if (stickies == null) {
18334 stickies = new ArrayMap<>();
18335 mStickyBroadcasts.put(userId, stickies);
18337 ArrayList<Intent> list = stickies.get(intent.getAction());
18338 if (list == null) {
18339 list = new ArrayList<>();
18340 stickies.put(intent.getAction(), list);
18342 final int stickiesCount = list.size();
18344 for (i = 0; i < stickiesCount; i++) {
18345 if (intent.filterEquals(list.get(i))) {
18346 // This sticky already exists, replace it.
18347 list.set(i, new Intent(intent));
18351 if (i >= stickiesCount) {
18352 list.add(new Intent(intent));
18357 if (userId == UserHandle.USER_ALL) {
18358 // Caller wants broadcast to go to all started users.
18359 users = mUserController.getStartedUserArrayLocked();
18361 // Caller wants broadcast to go to one specific user.
18362 users = new int[] {userId};
18365 // Figure out who all will receive this broadcast.
18366 List receivers = null;
18367 List<BroadcastFilter> registeredReceivers = null;
18368 // Need to resolve the intent to interested receivers...
18369 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18371 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18373 if (intent.getComponent() == null) {
18374 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18375 // Query one target user at a time, excluding shell-restricted users
18376 for (int i = 0; i < users.length; i++) {
18377 if (mUserController.hasUserRestriction(
18378 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18381 List<BroadcastFilter> registeredReceiversForUser =
18382 mReceiverResolver.queryIntent(intent,
18383 resolvedType, false, users[i]);
18384 if (registeredReceivers == null) {
18385 registeredReceivers = registeredReceiversForUser;
18386 } else if (registeredReceiversForUser != null) {
18387 registeredReceivers.addAll(registeredReceiversForUser);
18391 registeredReceivers = mReceiverResolver.queryIntent(intent,
18392 resolvedType, false, userId);
18396 final boolean replacePending =
18397 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18399 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18400 + " replacePending=" + replacePending);
18402 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18403 if (!ordered && NR > 0) {
18404 // If we are not serializing this broadcast, then send the
18405 // registered receivers separately so they don't wait for the
18406 // components to be launched.
18407 if (isCallerSystem) {
18408 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18409 isProtectedBroadcast, registeredReceivers);
18411 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18412 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18413 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18414 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18415 resultExtras, ordered, sticky, false, userId);
18416 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18417 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18419 queue.enqueueParallelBroadcastLocked(r);
18420 queue.scheduleBroadcastsLocked();
18422 registeredReceivers = null;
18426 // Merge into one list.
18428 if (receivers != null) {
18429 // A special case for PACKAGE_ADDED: do not allow the package
18430 // being added to see this broadcast. This prevents them from
18431 // using this as a back door to get run as soon as they are
18432 // installed. Maybe in the future we want to have a special install
18433 // broadcast or such for apps, but we'd like to deliberately make
18435 String skipPackages[] = null;
18436 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18437 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18438 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18439 Uri data = intent.getData();
18440 if (data != null) {
18441 String pkgName = data.getSchemeSpecificPart();
18442 if (pkgName != null) {
18443 skipPackages = new String[] { pkgName };
18446 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18447 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18449 if (skipPackages != null && (skipPackages.length > 0)) {
18450 for (String skipPackage : skipPackages) {
18451 if (skipPackage != null) {
18452 int NT = receivers.size();
18453 for (int it=0; it<NT; it++) {
18454 ResolveInfo curt = (ResolveInfo)receivers.get(it);
18455 if (curt.activityInfo.packageName.equals(skipPackage)) {
18456 receivers.remove(it);
18465 int NT = receivers != null ? receivers.size() : 0;
18467 ResolveInfo curt = null;
18468 BroadcastFilter curr = null;
18469 while (it < NT && ir < NR) {
18470 if (curt == null) {
18471 curt = (ResolveInfo)receivers.get(it);
18473 if (curr == null) {
18474 curr = registeredReceivers.get(ir);
18476 if (curr.getPriority() >= curt.priority) {
18477 // Insert this broadcast record into the final list.
18478 receivers.add(it, curr);
18484 // Skip to the next ResolveInfo in the final list.
18491 if (receivers == null) {
18492 receivers = new ArrayList();
18494 receivers.add(registeredReceivers.get(ir));
18498 if (isCallerSystem) {
18499 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18500 isProtectedBroadcast, receivers);
18503 if ((receivers != null && receivers.size() > 0)
18504 || resultTo != null) {
18505 BroadcastQueue queue = broadcastQueueForIntent(intent);
18506 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18507 callerPackage, callingPid, callingUid, resolvedType,
18508 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18509 resultData, resultExtras, ordered, sticky, false, userId);
18511 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18512 + ": prev had " + queue.mOrderedBroadcasts.size());
18513 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18514 "Enqueueing broadcast " + r.intent.getAction());
18516 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18518 queue.enqueueOrderedBroadcastLocked(r);
18519 queue.scheduleBroadcastsLocked();
18522 // There was nobody interested in the broadcast, but we still want to record
18523 // that it happened.
18524 if (intent.getComponent() == null && intent.getPackage() == null
18525 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18526 // This was an implicit broadcast... let's record it for posterity.
18527 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18531 return ActivityManager.BROADCAST_SUCCESS;
18534 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18535 int skipCount, long dispatchTime) {
18536 final long now = SystemClock.elapsedRealtime();
18537 if (mCurBroadcastStats == null ||
18538 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18539 mLastBroadcastStats = mCurBroadcastStats;
18540 if (mLastBroadcastStats != null) {
18541 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18542 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18544 mCurBroadcastStats = new BroadcastStats();
18546 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18549 final Intent verifyBroadcastLocked(Intent intent) {
18550 // Refuse possible leaked file descriptors
18551 if (intent != null && intent.hasFileDescriptors() == true) {
18552 throw new IllegalArgumentException("File descriptors passed in Intent");
18555 int flags = intent.getFlags();
18557 if (!mProcessesReady) {
18558 // if the caller really truly claims to know what they're doing, go
18559 // ahead and allow the broadcast without launching any receivers
18560 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18561 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18562 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18563 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18564 + " before boot completion");
18565 throw new IllegalStateException("Cannot broadcast before boot completed");
18569 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18570 throw new IllegalArgumentException(
18571 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18577 public final int broadcastIntent(IApplicationThread caller,
18578 Intent intent, String resolvedType, IIntentReceiver resultTo,
18579 int resultCode, String resultData, Bundle resultExtras,
18580 String[] requiredPermissions, int appOp, Bundle bOptions,
18581 boolean serialized, boolean sticky, int userId) {
18582 enforceNotIsolatedCaller("broadcastIntent");
18583 synchronized(this) {
18584 intent = verifyBroadcastLocked(intent);
18586 final ProcessRecord callerApp = getRecordForAppLocked(caller);
18587 final int callingPid = Binder.getCallingPid();
18588 final int callingUid = Binder.getCallingUid();
18589 final long origId = Binder.clearCallingIdentity();
18590 int res = broadcastIntentLocked(callerApp,
18591 callerApp != null ? callerApp.info.packageName : null,
18592 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18593 requiredPermissions, appOp, bOptions, serialized, sticky,
18594 callingPid, callingUid, userId);
18595 Binder.restoreCallingIdentity(origId);
18601 int broadcastIntentInPackage(String packageName, int uid,
18602 Intent intent, String resolvedType, IIntentReceiver resultTo,
18603 int resultCode, String resultData, Bundle resultExtras,
18604 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18606 synchronized(this) {
18607 intent = verifyBroadcastLocked(intent);
18609 final long origId = Binder.clearCallingIdentity();
18610 String[] requiredPermissions = requiredPermission == null ? null
18611 : new String[] {requiredPermission};
18612 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18613 resultTo, resultCode, resultData, resultExtras,
18614 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18615 sticky, -1, uid, userId);
18616 Binder.restoreCallingIdentity(origId);
18621 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18622 // Refuse possible leaked file descriptors
18623 if (intent != null && intent.hasFileDescriptors() == true) {
18624 throw new IllegalArgumentException("File descriptors passed in Intent");
18627 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18628 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18630 synchronized(this) {
18631 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18632 != PackageManager.PERMISSION_GRANTED) {
18633 String msg = "Permission Denial: unbroadcastIntent() from pid="
18634 + Binder.getCallingPid()
18635 + ", uid=" + Binder.getCallingUid()
18636 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18638 throw new SecurityException(msg);
18640 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18641 if (stickies != null) {
18642 ArrayList<Intent> list = stickies.get(intent.getAction());
18643 if (list != null) {
18644 int N = list.size();
18646 for (i=0; i<N; i++) {
18647 if (intent.filterEquals(list.get(i))) {
18652 if (list.size() <= 0) {
18653 stickies.remove(intent.getAction());
18656 if (stickies.size() <= 0) {
18657 mStickyBroadcasts.remove(userId);
18663 void backgroundServicesFinishedLocked(int userId) {
18664 for (BroadcastQueue queue : mBroadcastQueues) {
18665 queue.backgroundServicesFinishedLocked(userId);
18669 public void finishReceiver(IBinder who, int resultCode, String resultData,
18670 Bundle resultExtras, boolean resultAbort, int flags) {
18671 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18673 // Refuse possible leaked file descriptors
18674 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18675 throw new IllegalArgumentException("File descriptors passed in Bundle");
18678 final long origId = Binder.clearCallingIdentity();
18680 boolean doNext = false;
18683 synchronized(this) {
18684 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18685 ? mFgBroadcastQueue : mBgBroadcastQueue;
18686 r = queue.getMatchingOrderedReceiver(who);
18688 doNext = r.queue.finishReceiverLocked(r, resultCode,
18689 resultData, resultExtras, resultAbort, true);
18694 r.queue.processNextBroadcast(false);
18696 trimApplications();
18698 Binder.restoreCallingIdentity(origId);
18702 // =========================================================
18704 // =========================================================
18706 public boolean startInstrumentation(ComponentName className,
18707 String profileFile, int flags, Bundle arguments,
18708 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18709 int userId, String abiOverride) {
18710 enforceNotIsolatedCaller("startInstrumentation");
18711 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18712 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18713 // Refuse possible leaked file descriptors
18714 if (arguments != null && arguments.hasFileDescriptors()) {
18715 throw new IllegalArgumentException("File descriptors passed in Bundle");
18718 synchronized(this) {
18719 InstrumentationInfo ii = null;
18720 ApplicationInfo ai = null;
18722 ii = mContext.getPackageManager().getInstrumentationInfo(
18723 className, STOCK_PM_FLAGS);
18724 ai = AppGlobals.getPackageManager().getApplicationInfo(
18725 ii.targetPackage, STOCK_PM_FLAGS, userId);
18726 } catch (PackageManager.NameNotFoundException e) {
18727 } catch (RemoteException e) {
18730 reportStartInstrumentationFailureLocked(watcher, className,
18731 "Unable to find instrumentation info for: " + className);
18735 reportStartInstrumentationFailureLocked(watcher, className,
18736 "Unable to find instrumentation target package: " + ii.targetPackage);
18739 if (!ai.hasCode()) {
18740 reportStartInstrumentationFailureLocked(watcher, className,
18741 "Instrumentation target has no code: " + ii.targetPackage);
18745 int match = mContext.getPackageManager().checkSignatures(
18746 ii.targetPackage, ii.packageName);
18747 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18748 String msg = "Permission Denial: starting instrumentation "
18749 + className + " from pid="
18750 + Binder.getCallingPid()
18751 + ", uid=" + Binder.getCallingPid()
18752 + " not allowed because package " + ii.packageName
18753 + " does not have a signature matching the target "
18754 + ii.targetPackage;
18755 reportStartInstrumentationFailureLocked(watcher, className, msg);
18756 throw new SecurityException(msg);
18759 final long origId = Binder.clearCallingIdentity();
18760 // Instrumentation can kill and relaunch even persistent processes
18761 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18763 ProcessRecord app = addAppLocked(ai, false, abiOverride);
18764 app.instrumentationClass = className;
18765 app.instrumentationInfo = ai;
18766 app.instrumentationProfileFile = profileFile;
18767 app.instrumentationArguments = arguments;
18768 app.instrumentationWatcher = watcher;
18769 app.instrumentationUiAutomationConnection = uiAutomationConnection;
18770 app.instrumentationResultClass = className;
18771 Binder.restoreCallingIdentity(origId);
18778 * Report errors that occur while attempting to start Instrumentation. Always writes the
18779 * error to the logs, but if somebody is watching, send the report there too. This enables
18780 * the "am" command to report errors with more information.
18782 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
18783 * @param cn The component name of the instrumentation.
18784 * @param report The error report.
18786 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18787 ComponentName cn, String report) {
18788 Slog.w(TAG, report);
18789 if (watcher != null) {
18790 Bundle results = new Bundle();
18791 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18792 results.putString("Error", report);
18793 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18797 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18798 if (app.instrumentationWatcher != null) {
18799 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18800 app.instrumentationClass, resultCode, results);
18803 // Can't call out of the system process with a lock held, so post a message.
18804 if (app.instrumentationUiAutomationConnection != null) {
18805 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18806 app.instrumentationUiAutomationConnection).sendToTarget();
18809 app.instrumentationWatcher = null;
18810 app.instrumentationUiAutomationConnection = null;
18811 app.instrumentationClass = null;
18812 app.instrumentationInfo = null;
18813 app.instrumentationProfileFile = null;
18814 app.instrumentationArguments = null;
18816 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18820 public void finishInstrumentation(IApplicationThread target,
18821 int resultCode, Bundle results) {
18822 int userId = UserHandle.getCallingUserId();
18823 // Refuse possible leaked file descriptors
18824 if (results != null && results.hasFileDescriptors()) {
18825 throw new IllegalArgumentException("File descriptors passed in Intent");
18828 synchronized(this) {
18829 ProcessRecord app = getRecordForAppLocked(target);
18831 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18834 final long origId = Binder.clearCallingIdentity();
18835 finishInstrumentationLocked(app, resultCode, results);
18836 Binder.restoreCallingIdentity(origId);
18840 // =========================================================
18842 // =========================================================
18844 public ConfigurationInfo getDeviceConfigurationInfo() {
18845 ConfigurationInfo config = new ConfigurationInfo();
18846 synchronized (this) {
18847 config.reqTouchScreen = mConfiguration.touchscreen;
18848 config.reqKeyboardType = mConfiguration.keyboard;
18849 config.reqNavigation = mConfiguration.navigation;
18850 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18851 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18852 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18854 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18855 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18856 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18858 config.reqGlEsVersion = GL_ES_VERSION;
18863 ActivityStack getFocusedStack() {
18864 return mStackSupervisor.getFocusedStack();
18868 public int getFocusedStackId() throws RemoteException {
18869 ActivityStack focusedStack = getFocusedStack();
18870 if (focusedStack != null) {
18871 return focusedStack.getStackId();
18876 public Configuration getConfiguration() {
18878 synchronized(this) {
18879 ci = new Configuration(mConfiguration);
18880 ci.userSetLocale = false;
18886 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18887 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18888 synchronized (this) {
18889 mSuppressResizeConfigChanges = suppress;
18894 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18895 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18896 if (fromStackId == HOME_STACK_ID) {
18897 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18899 synchronized (this) {
18900 final long origId = Binder.clearCallingIdentity();
18902 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18904 Binder.restoreCallingIdentity(origId);
18910 public void updatePersistentConfiguration(Configuration values) {
18911 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18912 "updateConfiguration()");
18913 enforceWriteSettingsPermission("updateConfiguration()");
18914 if (values == null) {
18915 throw new NullPointerException("Configuration must not be null");
18918 int userId = UserHandle.getCallingUserId();
18920 synchronized(this) {
18921 updatePersistentConfigurationLocked(values, userId);
18925 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18926 final long origId = Binder.clearCallingIdentity();
18928 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18930 Binder.restoreCallingIdentity(origId);
18934 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18935 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18936 FONT_SCALE, 1.0f, userId);
18937 if (mConfiguration.fontScale != scaleFactor) {
18938 final Configuration configuration = mWindowManager.computeNewConfiguration();
18939 configuration.fontScale = scaleFactor;
18940 synchronized (this) {
18941 updatePersistentConfigurationLocked(configuration, userId);
18946 private void enforceWriteSettingsPermission(String func) {
18947 int uid = Binder.getCallingUid();
18948 if (uid == Process.ROOT_UID) {
18952 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18953 Settings.getPackageNameForUid(mContext, uid), false)) {
18957 String msg = "Permission Denial: " + func + " from pid="
18958 + Binder.getCallingPid()
18960 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18962 throw new SecurityException(msg);
18965 public void updateConfiguration(Configuration values) {
18966 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18967 "updateConfiguration()");
18969 synchronized(this) {
18970 if (values == null && mWindowManager != null) {
18971 // sentinel: fetch the current configuration from the window manager
18972 values = mWindowManager.computeNewConfiguration();
18975 if (mWindowManager != null) {
18976 mProcessList.applyDisplaySize(mWindowManager);
18979 final long origId = Binder.clearCallingIdentity();
18980 if (values != null) {
18981 Settings.System.clearConfiguration(values);
18983 updateConfigurationLocked(values, null, false);
18984 Binder.restoreCallingIdentity(origId);
18988 void updateUserConfigurationLocked() {
18989 Configuration configuration = new Configuration(mConfiguration);
18990 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18991 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18992 updateConfigurationLocked(configuration, null, false);
18995 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18996 boolean initLocale) {
18997 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19000 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19001 boolean initLocale, boolean deferResume) {
19002 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19003 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19004 UserHandle.USER_NULL, deferResume);
19007 // To cache the list of supported system locales
19008 private String[] mSupportedSystemLocales = null;
19011 * Do either or both things: (1) change the current configuration, and (2)
19012 * make sure the given activity is running with the (now) current
19013 * configuration. Returns true if the activity has been left running, or
19014 * false if <var>starting</var> is being destroyed to match the new
19017 * @param userId is only used when persistent parameter is set to true to persist configuration
19018 * for that particular user
19020 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19021 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19024 if (mWindowManager != null) {
19025 mWindowManager.deferSurfaceLayout();
19027 if (values != null) {
19028 Configuration newConfig = new Configuration(mConfiguration);
19029 changes = newConfig.updateFrom(values);
19030 if (changes != 0) {
19031 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19032 "Updating configuration to: " + values);
19034 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19036 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19037 final LocaleList locales = values.getLocales();
19038 int bestLocaleIndex = 0;
19039 if (locales.size() > 1) {
19040 if (mSupportedSystemLocales == null) {
19041 mSupportedSystemLocales =
19042 Resources.getSystem().getAssets().getLocales();
19044 bestLocaleIndex = Math.max(0,
19045 locales.getFirstMatchIndex(mSupportedSystemLocales));
19047 SystemProperties.set("persist.sys.locale",
19048 locales.get(bestLocaleIndex).toLanguageTag());
19049 LocaleList.setDefault(locales, bestLocaleIndex);
19050 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19051 locales.get(bestLocaleIndex)));
19054 mConfigurationSeq++;
19055 if (mConfigurationSeq <= 0) {
19056 mConfigurationSeq = 1;
19058 newConfig.seq = mConfigurationSeq;
19059 mConfiguration = newConfig;
19060 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19061 mUsageStatsService.reportConfigurationChange(newConfig,
19062 mUserController.getCurrentUserIdLocked());
19063 //mUsageStatsService.noteStartConfig(newConfig);
19065 final Configuration configCopy = new Configuration(mConfiguration);
19067 // TODO: If our config changes, should we auto dismiss any currently
19068 // showing dialogs?
19069 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19071 AttributeCache ac = AttributeCache.instance();
19073 ac.updateConfiguration(configCopy);
19076 // Make sure all resources in our process are updated
19077 // right now, so that anyone who is going to retrieve
19078 // resource values after we return will be sure to get
19079 // the new ones. This is especially important during
19080 // boot, where the first config change needs to guarantee
19081 // all resources have that config before following boot
19082 // code is executed.
19083 mSystemThread.applyConfigurationToResources(configCopy);
19085 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19086 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19087 msg.obj = new Configuration(configCopy);
19089 mHandler.sendMessage(msg);
19092 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19093 if (isDensityChange) {
19094 // Reset the unsupported display size dialog.
19095 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19097 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19098 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19101 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19102 ProcessRecord app = mLruProcesses.get(i);
19104 if (app.thread != null) {
19105 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19106 + app.processName + " new config " + mConfiguration);
19107 app.thread.scheduleConfigurationChanged(configCopy);
19109 } catch (Exception e) {
19112 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19113 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19114 | Intent.FLAG_RECEIVER_REPLACE_PENDING
19115 | Intent.FLAG_RECEIVER_FOREGROUND);
19116 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19117 null, AppOpsManager.OP_NONE, null, false, false,
19118 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19119 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19120 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19121 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19122 if (initLocale || !mProcessesReady) {
19123 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19125 broadcastIntentLocked(null, null, intent,
19126 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19127 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19130 // Update the configuration with WM first and check if any of the stacks need to be
19131 // resized due to the configuration change. If so, resize the stacks now and do any
19132 // relaunches if necessary. This way we don't need to relaunch again below in
19133 // ensureActivityConfigurationLocked().
19134 if (mWindowManager != null) {
19135 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19136 if (resizedStacks != null) {
19137 for (int stackId : resizedStacks) {
19138 final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19139 mStackSupervisor.resizeStackLocked(
19140 stackId, newBounds, null, null, false, false, deferResume);
19146 boolean kept = true;
19147 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19148 // mainStack is null during startup.
19149 if (mainStack != null) {
19150 if (changes != 0 && starting == null) {
19151 // If the configuration changed, and the caller is not already
19152 // in the process of starting an activity, then find the top
19153 // activity to check if its configuration needs to change.
19154 starting = mainStack.topRunningActivityLocked();
19157 if (starting != null) {
19158 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19159 // And we need to make sure at this point that all other activities
19160 // are made visible with the correct configuration.
19161 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19162 !PRESERVE_WINDOWS);
19165 if (mWindowManager != null) {
19166 mWindowManager.continueSurfaceLayout();
19172 * Decide based on the configuration whether we should shouw the ANR,
19173 * crash, etc dialogs. The idea is that if there is no affordence to
19174 * press the on-screen buttons, or the user experience would be more
19175 * greatly impacted than the crash itself, we shouldn't show the dialog.
19177 * A thought: SystemUI might also want to get told about this, the Power
19178 * dialog / global actions also might want different behaviors.
19180 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19181 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19182 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19183 && config.navigation == Configuration.NAVIGATION_NONAV);
19184 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19185 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19186 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19187 return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19191 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19192 synchronized (this) {
19193 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19194 if (srec != null) {
19195 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19201 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19202 Intent resultData) {
19204 synchronized (this) {
19205 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19207 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19213 public int getLaunchedFromUid(IBinder activityToken) {
19214 ActivityRecord srec;
19215 synchronized (this) {
19216 srec = ActivityRecord.forTokenLocked(activityToken);
19218 if (srec == null) {
19221 return srec.launchedFromUid;
19224 public String getLaunchedFromPackage(IBinder activityToken) {
19225 ActivityRecord srec;
19226 synchronized (this) {
19227 srec = ActivityRecord.forTokenLocked(activityToken);
19229 if (srec == null) {
19232 return srec.launchedFromPackage;
19235 // =========================================================
19236 // LIFETIME MANAGEMENT
19237 // =========================================================
19239 // Returns which broadcast queue the app is the current [or imminent] receiver
19240 // on, or 'null' if the app is not an active broadcast recipient.
19241 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19242 BroadcastRecord r = app.curReceiver;
19247 // It's not the current receiver, but it might be starting up to become one
19248 synchronized (this) {
19249 for (BroadcastQueue queue : mBroadcastQueues) {
19250 r = queue.mPendingBroadcast;
19251 if (r != null && r.curApp == app) {
19252 // found it; report which queue it's in
19261 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19262 int targetUid, ComponentName targetComponent, String targetProcess) {
19263 if (!mTrackingAssociations) {
19266 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19267 = mAssociations.get(targetUid);
19268 if (components == null) {
19269 components = new ArrayMap<>();
19270 mAssociations.put(targetUid, components);
19272 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19273 if (sourceUids == null) {
19274 sourceUids = new SparseArray<>();
19275 components.put(targetComponent, sourceUids);
19277 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19278 if (sourceProcesses == null) {
19279 sourceProcesses = new ArrayMap<>();
19280 sourceUids.put(sourceUid, sourceProcesses);
19282 Association ass = sourceProcesses.get(sourceProcess);
19284 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19286 sourceProcesses.put(sourceProcess, ass);
19290 if (ass.mNesting == 1) {
19291 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19292 ass.mLastState = sourceState;
19297 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19298 ComponentName targetComponent) {
19299 if (!mTrackingAssociations) {
19302 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19303 = mAssociations.get(targetUid);
19304 if (components == null) {
19307 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19308 if (sourceUids == null) {
19311 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19312 if (sourceProcesses == null) {
19315 Association ass = sourceProcesses.get(sourceProcess);
19316 if (ass == null || ass.mNesting <= 0) {
19320 if (ass.mNesting == 0) {
19321 long uptime = SystemClock.uptimeMillis();
19322 ass.mTime += uptime - ass.mStartTime;
19323 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19324 += uptime - ass.mLastStateUptime;
19325 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19329 private void noteUidProcessState(final int uid, final int state) {
19330 mBatteryStatsService.noteUidProcessState(uid, state);
19331 if (mTrackingAssociations) {
19332 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19333 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19334 = mAssociations.valueAt(i1);
19335 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19336 SparseArray<ArrayMap<String, Association>> sourceUids
19337 = targetComponents.valueAt(i2);
19338 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19339 if (sourceProcesses != null) {
19340 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19341 Association ass = sourceProcesses.valueAt(i4);
19342 if (ass.mNesting >= 1) {
19343 // currently associated
19344 long uptime = SystemClock.uptimeMillis();
19345 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19346 += uptime - ass.mLastStateUptime;
19347 ass.mLastState = state;
19348 ass.mLastStateUptime = uptime;
19357 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19358 boolean doingAll, long now) {
19359 if (mAdjSeq == app.adjSeq) {
19360 // This adjustment has already been computed.
19361 return app.curRawAdj;
19364 if (app.thread == null) {
19365 app.adjSeq = mAdjSeq;
19366 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19367 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19368 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19371 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19372 app.adjSource = null;
19373 app.adjTarget = null;
19375 app.cached = false;
19377 final int activitiesSize = app.activities.size();
19379 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19380 // The max adjustment doesn't allow this app to be anything
19381 // below foreground, so it is not worth doing work for it.
19382 app.adjType = "fixed";
19383 app.adjSeq = mAdjSeq;
19384 app.curRawAdj = app.maxAdj;
19385 app.foregroundActivities = false;
19386 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19387 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19388 // System processes can do UI, and when they do we want to have
19389 // them trim their memory after the user leaves the UI. To
19390 // facilitate this, here we need to determine whether or not it
19391 // is currently showing UI.
19392 app.systemNoUi = true;
19393 if (app == TOP_APP) {
19394 app.systemNoUi = false;
19395 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19396 app.adjType = "pers-top-activity";
19397 } else if (app.hasTopUi) {
19398 app.systemNoUi = false;
19399 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19400 app.adjType = "pers-top-ui";
19401 } else if (activitiesSize > 0) {
19402 for (int j = 0; j < activitiesSize; j++) {
19403 final ActivityRecord r = app.activities.get(j);
19405 app.systemNoUi = false;
19409 if (!app.systemNoUi) {
19410 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19412 return (app.curAdj=app.maxAdj);
19415 app.systemNoUi = false;
19417 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19419 // Determine the importance of the process, starting with most
19420 // important to least, and assign an appropriate OOM adjustment.
19424 boolean foregroundActivities = false;
19425 BroadcastQueue queue;
19426 if (app == TOP_APP) {
19427 // The last app on the list is the foreground app.
19428 adj = ProcessList.FOREGROUND_APP_ADJ;
19429 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19430 app.adjType = "top-activity";
19431 foregroundActivities = true;
19432 procState = PROCESS_STATE_CUR_TOP;
19433 } else if (app.instrumentationClass != null) {
19434 // Don't want to kill running instrumentation.
19435 adj = ProcessList.FOREGROUND_APP_ADJ;
19436 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19437 app.adjType = "instrumentation";
19438 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19439 } else if ((queue = isReceivingBroadcast(app)) != null) {
19440 // An app that is currently receiving a broadcast also
19441 // counts as being in the foreground for OOM killer purposes.
19442 // It's placed in a sched group based on the nature of the
19443 // broadcast as reflected by which queue it's active in.
19444 adj = ProcessList.FOREGROUND_APP_ADJ;
19445 schedGroup = (queue == mFgBroadcastQueue)
19446 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19447 app.adjType = "broadcast";
19448 procState = ActivityManager.PROCESS_STATE_RECEIVER;
19449 } else if (app.executingServices.size() > 0) {
19450 // An app that is currently executing a service callback also
19451 // counts as being in the foreground.
19452 adj = ProcessList.FOREGROUND_APP_ADJ;
19453 schedGroup = app.execServicesFg ?
19454 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19455 app.adjType = "exec-service";
19456 procState = ActivityManager.PROCESS_STATE_SERVICE;
19457 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19459 // As far as we know the process is empty. We may change our mind later.
19460 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19461 // At this point we don't actually know the adjustment. Use the cached adj
19462 // value that the caller wants us to.
19464 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19467 app.adjType = "cch-empty";
19470 // Examine all activities if not already foreground.
19471 if (!foregroundActivities && activitiesSize > 0) {
19472 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19473 for (int j = 0; j < activitiesSize; j++) {
19474 final ActivityRecord r = app.activities.get(j);
19475 if (r.app != app) {
19476 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19477 + " instead of expected " + app);
19478 if (r.app == null || (r.app.uid == app.uid)) {
19479 // Only fix things up when they look sane
19486 // App has a visible activity; only upgrade adjustment.
19487 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19488 adj = ProcessList.VISIBLE_APP_ADJ;
19489 app.adjType = "visible";
19491 if (procState > PROCESS_STATE_CUR_TOP) {
19492 procState = PROCESS_STATE_CUR_TOP;
19494 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19495 app.cached = false;
19497 foregroundActivities = true;
19498 if (r.task != null && minLayer > 0) {
19499 final int layer = r.task.mLayerRank;
19500 if (layer >= 0 && minLayer > layer) {
19505 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19506 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19507 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19508 app.adjType = "pausing";
19510 if (procState > PROCESS_STATE_CUR_TOP) {
19511 procState = PROCESS_STATE_CUR_TOP;
19513 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19514 app.cached = false;
19516 foregroundActivities = true;
19517 } else if (r.state == ActivityState.STOPPING) {
19518 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19519 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19520 app.adjType = "stopping";
19522 // For the process state, we will at this point consider the
19523 // process to be cached. It will be cached either as an activity
19524 // or empty depending on whether the activity is finishing. We do
19525 // this so that we can treat the process as cached for purposes of
19526 // memory trimming (determing current memory level, trim command to
19527 // send to process) since there can be an arbitrary number of stopping
19528 // processes and they should soon all go into the cached state.
19529 if (!r.finishing) {
19530 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19531 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19534 app.cached = false;
19536 foregroundActivities = true;
19538 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19539 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19540 app.adjType = "cch-act";
19544 if (adj == ProcessList.VISIBLE_APP_ADJ) {
19549 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19550 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19551 if (app.foregroundServices) {
19552 // The user is aware of this app, so make it visible.
19553 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19554 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19555 app.cached = false;
19556 app.adjType = "fg-service";
19557 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19558 } else if (app.forcingToForeground != null) {
19559 // The user is aware of this app, so make it visible.
19560 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19561 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19562 app.cached = false;
19563 app.adjType = "force-fg";
19564 app.adjSource = app.forcingToForeground;
19565 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19569 if (app == mHeavyWeightProcess) {
19570 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19571 // We don't want to kill the current heavy-weight process.
19572 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19573 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19574 app.cached = false;
19575 app.adjType = "heavy";
19577 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19578 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19582 if (app == mHomeProcess) {
19583 if (adj > ProcessList.HOME_APP_ADJ) {
19584 // This process is hosting what we currently consider to be the
19585 // home app, so we don't want to let it go into the background.
19586 adj = ProcessList.HOME_APP_ADJ;
19587 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19588 app.cached = false;
19589 app.adjType = "home";
19591 if (procState > ActivityManager.PROCESS_STATE_HOME) {
19592 procState = ActivityManager.PROCESS_STATE_HOME;
19596 if (app == mPreviousProcess && app.activities.size() > 0) {
19597 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19598 // This was the previous process that showed UI to the user.
19599 // We want to try to keep it around more aggressively, to give
19600 // a good experience around switching between two apps.
19601 adj = ProcessList.PREVIOUS_APP_ADJ;
19602 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19603 app.cached = false;
19604 app.adjType = "previous";
19606 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19607 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19611 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19612 + " reason=" + app.adjType);
19614 // By default, we use the computed adjustment. It may be changed if
19615 // there are applications dependent on our services or providers, but
19616 // this gives us a baseline and makes sure we don't get into an
19617 // infinite recursion.
19618 app.adjSeq = mAdjSeq;
19619 app.curRawAdj = adj;
19620 app.hasStartedServices = false;
19622 if (mBackupTarget != null && app == mBackupTarget.app) {
19623 // If possible we want to avoid killing apps while they're being backed up
19624 if (adj > ProcessList.BACKUP_APP_ADJ) {
19625 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19626 adj = ProcessList.BACKUP_APP_ADJ;
19627 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19628 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19630 app.adjType = "backup";
19631 app.cached = false;
19633 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19634 procState = ActivityManager.PROCESS_STATE_BACKUP;
19638 boolean mayBeTop = false;
19640 for (int is = app.services.size()-1;
19641 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19642 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19643 || procState > ActivityManager.PROCESS_STATE_TOP);
19645 ServiceRecord s = app.services.valueAt(is);
19646 if (s.startRequested) {
19647 app.hasStartedServices = true;
19648 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19649 procState = ActivityManager.PROCESS_STATE_SERVICE;
19651 if (app.hasShownUi && app != mHomeProcess) {
19652 // If this process has shown some UI, let it immediately
19653 // go to the LRU list because it may be pretty heavy with
19654 // UI stuff. We'll tag it with a label just to help
19655 // debug and understand what is going on.
19656 if (adj > ProcessList.SERVICE_ADJ) {
19657 app.adjType = "cch-started-ui-services";
19660 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19661 // This service has seen some activity within
19662 // recent memory, so we will keep its process ahead
19663 // of the background processes.
19664 if (adj > ProcessList.SERVICE_ADJ) {
19665 adj = ProcessList.SERVICE_ADJ;
19666 app.adjType = "started-services";
19667 app.cached = false;
19670 // If we have let the service slide into the background
19671 // state, still have some text describing what it is doing
19672 // even though the service no longer has an impact.
19673 if (adj > ProcessList.SERVICE_ADJ) {
19674 app.adjType = "cch-started-services";
19679 for (int conni = s.connections.size()-1;
19680 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19681 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19682 || procState > ActivityManager.PROCESS_STATE_TOP);
19684 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19686 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19687 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19688 || procState > ActivityManager.PROCESS_STATE_TOP);
19690 // XXX should compute this based on the max of
19691 // all connected clients.
19692 ConnectionRecord cr = clist.get(i);
19693 if (cr.binding.client == app) {
19694 // Binding to ourself is not interesting.
19698 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19699 ProcessRecord client = cr.binding.client;
19700 int clientAdj = computeOomAdjLocked(client, cachedAdj,
19701 TOP_APP, doingAll, now);
19702 int clientProcState = client.curProcState;
19703 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19704 // If the other app is cached for any reason, for purposes here
19705 // we are going to consider it empty. The specific cached state
19706 // doesn't propagate except under certain conditions.
19707 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19709 String adjType = null;
19710 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19711 // Not doing bind OOM management, so treat
19712 // this guy more like a started service.
19713 if (app.hasShownUi && app != mHomeProcess) {
19714 // If this process has shown some UI, let it immediately
19715 // go to the LRU list because it may be pretty heavy with
19716 // UI stuff. We'll tag it with a label just to help
19717 // debug and understand what is going on.
19718 if (adj > clientAdj) {
19719 adjType = "cch-bound-ui-services";
19721 app.cached = false;
19723 clientProcState = procState;
19725 if (now >= (s.lastActivity
19726 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19727 // This service has not seen activity within
19728 // recent memory, so allow it to drop to the
19729 // LRU list if there is no other reason to keep
19730 // it around. We'll also tag it with a label just
19731 // to help debug and undertand what is going on.
19732 if (adj > clientAdj) {
19733 adjType = "cch-bound-services";
19739 if (adj > clientAdj) {
19740 // If this process has recently shown UI, and
19741 // the process that is binding to it is less
19742 // important than being visible, then we don't
19743 // care about the binding as much as we care
19744 // about letting this process get into the LRU
19745 // list to be killed and restarted if needed for
19747 if (app.hasShownUi && app != mHomeProcess
19748 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19749 adjType = "cch-bound-ui-services";
19751 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19752 |Context.BIND_IMPORTANT)) != 0) {
19753 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19754 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19755 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19756 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19757 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19758 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19759 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19762 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19763 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19766 if (!client.cached) {
19767 app.cached = false;
19769 adjType = "service";
19772 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19773 // This will treat important bound services identically to
19774 // the top app, which may behave differently than generic
19775 // foreground work.
19776 if (client.curSchedGroup > schedGroup) {
19777 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19778 schedGroup = client.curSchedGroup;
19780 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19783 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19784 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19785 // Special handling of clients who are in the top state.
19786 // We *may* want to consider this process to be in the
19787 // top state as well, but only if there is not another
19788 // reason for it to be running. Being on the top is a
19789 // special state, meaning you are specifically running
19790 // for the current top app. If the process is already
19791 // running in the background for some other reason, it
19792 // is more important to continue considering it to be
19793 // in the background state.
19795 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19797 // Special handling for above-top states (persistent
19798 // processes). These should not bring the current process
19799 // into the top state, since they are not on top. Instead
19800 // give them the best state after that.
19801 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19803 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19804 } else if (mWakefulness
19805 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19806 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19809 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19812 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19817 if (clientProcState <
19818 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19820 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19823 if (procState > clientProcState) {
19824 procState = clientProcState;
19826 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19827 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19828 app.pendingUiClean = true;
19830 if (adjType != null) {
19831 app.adjType = adjType;
19832 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19833 .REASON_SERVICE_IN_USE;
19834 app.adjSource = cr.binding.client;
19835 app.adjSourceProcState = clientProcState;
19836 app.adjTarget = s.name;
19839 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19840 app.treatLikeActivity = true;
19842 final ActivityRecord a = cr.activity;
19843 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19844 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19845 (a.visible || a.state == ActivityState.RESUMED ||
19846 a.state == ActivityState.PAUSING)) {
19847 adj = ProcessList.FOREGROUND_APP_ADJ;
19848 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19849 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19850 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19852 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19855 app.cached = false;
19856 app.adjType = "service";
19857 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19858 .REASON_SERVICE_IN_USE;
19860 app.adjSourceProcState = procState;
19861 app.adjTarget = s.name;
19868 for (int provi = app.pubProviders.size()-1;
19869 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19870 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19871 || procState > ActivityManager.PROCESS_STATE_TOP);
19873 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19874 for (int i = cpr.connections.size()-1;
19875 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19876 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19877 || procState > ActivityManager.PROCESS_STATE_TOP);
19879 ContentProviderConnection conn = cpr.connections.get(i);
19880 ProcessRecord client = conn.client;
19881 if (client == app) {
19882 // Being our own client is not interesting.
19885 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19886 int clientProcState = client.curProcState;
19887 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19888 // If the other app is cached for any reason, for purposes here
19889 // we are going to consider it empty.
19890 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19892 if (adj > clientAdj) {
19893 if (app.hasShownUi && app != mHomeProcess
19894 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19895 app.adjType = "cch-ui-provider";
19897 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19898 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19899 app.adjType = "provider";
19901 app.cached &= client.cached;
19902 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19903 .REASON_PROVIDER_IN_USE;
19904 app.adjSource = client;
19905 app.adjSourceProcState = clientProcState;
19906 app.adjTarget = cpr.name;
19908 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19909 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19910 // Special handling of clients who are in the top state.
19911 // We *may* want to consider this process to be in the
19912 // top state as well, but only if there is not another
19913 // reason for it to be running. Being on the top is a
19914 // special state, meaning you are specifically running
19915 // for the current top app. If the process is already
19916 // running in the background for some other reason, it
19917 // is more important to continue considering it to be
19918 // in the background state.
19920 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19922 // Special handling for above-top states (persistent
19923 // processes). These should not bring the current process
19924 // into the top state, since they are not on top. Instead
19925 // give them the best state after that.
19927 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19930 if (procState > clientProcState) {
19931 procState = clientProcState;
19933 if (client.curSchedGroup > schedGroup) {
19934 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19937 // If the provider has external (non-framework) process
19938 // dependencies, ensure that its adjustment is at least
19939 // FOREGROUND_APP_ADJ.
19940 if (cpr.hasExternalProcessHandles()) {
19941 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19942 adj = ProcessList.FOREGROUND_APP_ADJ;
19943 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19944 app.cached = false;
19945 app.adjType = "provider";
19946 app.adjTarget = cpr.name;
19948 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19949 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19954 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19955 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19956 adj = ProcessList.PREVIOUS_APP_ADJ;
19957 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19958 app.cached = false;
19959 app.adjType = "provider";
19961 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19962 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19966 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19967 // A client of one of our services or providers is in the top state. We
19968 // *may* want to be in the top state, but not if we are already running in
19969 // the background for some other reason. For the decision here, we are going
19970 // to pick out a few specific states that we want to remain in when a client
19971 // is top (states that tend to be longer-term) and otherwise allow it to go
19972 // to the top state.
19973 switch (procState) {
19974 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19975 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19976 case ActivityManager.PROCESS_STATE_SERVICE:
19977 // These all are longer-term states, so pull them up to the top
19978 // of the background states, but not all the way to the top state.
19979 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19982 // Otherwise, top is a better choice, so take it.
19983 procState = ActivityManager.PROCESS_STATE_TOP;
19988 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19989 if (app.hasClientActivities) {
19990 // This is a cached process, but with client activities. Mark it so.
19991 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19992 app.adjType = "cch-client-act";
19993 } else if (app.treatLikeActivity) {
19994 // This is a cached process, but somebody wants us to treat it like it has
19995 // an activity, okay!
19996 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19997 app.adjType = "cch-as-act";
20001 if (adj == ProcessList.SERVICE_ADJ) {
20003 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20004 mNewNumServiceProcs++;
20005 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20006 if (!app.serviceb) {
20007 // This service isn't far enough down on the LRU list to
20008 // normally be a B service, but if we are low on RAM and it
20009 // is large we want to force it down since we would prefer to
20010 // keep launcher over it.
20011 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20012 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20013 app.serviceHighRam = true;
20014 app.serviceb = true;
20015 //Slog.i(TAG, "ADJ " + app + " high ram!");
20017 mNewNumAServiceProcs++;
20018 //Slog.i(TAG, "ADJ " + app + " not high ram!");
20021 app.serviceHighRam = false;
20024 if (app.serviceb) {
20025 adj = ProcessList.SERVICE_B_ADJ;
20029 app.curRawAdj = adj;
20031 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20032 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20033 if (adj > app.maxAdj) {
20035 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20036 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20040 // Do final modification to adj. Everything we do between here and applying
20041 // the final setAdj must be done in this function, because we will also use
20042 // it when computing the final cached adj later. Note that we don't need to
20043 // worry about this for max adj above, since max adj will always be used to
20044 // keep it out of the cached vaues.
20045 app.curAdj = app.modifyRawOomAdj(adj);
20046 app.curSchedGroup = schedGroup;
20047 app.curProcState = procState;
20048 app.foregroundActivities = foregroundActivities;
20050 return app.curRawAdj;
20054 * Record new PSS sample for a process.
20056 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20058 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20060 proc.lastPssTime = now;
20061 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20062 if (DEBUG_PSS) Slog.d(TAG_PSS,
20063 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20064 + " state=" + ProcessList.makeProcStateString(procState));
20065 if (proc.initialIdlePss == 0) {
20066 proc.initialIdlePss = pss;
20068 proc.lastPss = pss;
20069 proc.lastSwapPss = swapPss;
20070 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20071 proc.lastCachedPss = pss;
20072 proc.lastCachedSwapPss = swapPss;
20075 final SparseArray<Pair<Long, String>> watchUids
20076 = mMemWatchProcesses.getMap().get(proc.processName);
20078 if (watchUids != null) {
20079 Pair<Long, String> val = watchUids.get(proc.uid);
20081 val = watchUids.get(0);
20087 if (check != null) {
20088 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20089 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20090 if (!isDebuggable) {
20091 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20092 isDebuggable = true;
20095 if (isDebuggable) {
20096 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20097 final ProcessRecord myProc = proc;
20098 final File heapdumpFile = DumpHeapProvider.getJavaFile();
20099 mMemWatchDumpProcName = proc.processName;
20100 mMemWatchDumpFile = heapdumpFile.toString();
20101 mMemWatchDumpPid = proc.pid;
20102 mMemWatchDumpUid = proc.uid;
20103 BackgroundThread.getHandler().post(new Runnable() {
20105 public void run() {
20106 revokeUriPermission(ActivityThread.currentActivityThread()
20107 .getApplicationThread(),
20108 DumpHeapActivity.JAVA_URI,
20109 Intent.FLAG_GRANT_READ_URI_PERMISSION
20110 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20111 UserHandle.myUserId());
20112 ParcelFileDescriptor fd = null;
20114 heapdumpFile.delete();
20115 fd = ParcelFileDescriptor.open(heapdumpFile,
20116 ParcelFileDescriptor.MODE_CREATE |
20117 ParcelFileDescriptor.MODE_TRUNCATE |
20118 ParcelFileDescriptor.MODE_WRITE_ONLY |
20119 ParcelFileDescriptor.MODE_APPEND);
20120 IApplicationThread thread = myProc.thread;
20121 if (thread != null) {
20123 if (DEBUG_PSS) Slog.d(TAG_PSS,
20124 "Requesting dump heap from "
20125 + myProc + " to " + heapdumpFile);
20126 thread.dumpHeap(true, heapdumpFile.toString(), fd);
20127 } catch (RemoteException e) {
20130 } catch (FileNotFoundException e) {
20131 e.printStackTrace();
20136 } catch (IOException e) {
20143 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20144 + ", but debugging not enabled");
20151 * Schedule PSS collection of a process.
20153 void requestPssLocked(ProcessRecord proc, int procState) {
20154 if (mPendingPssProcesses.contains(proc)) {
20157 if (mPendingPssProcesses.size() == 0) {
20158 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20160 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20161 proc.pssProcState = procState;
20162 mPendingPssProcesses.add(proc);
20166 * Schedule PSS collection of all processes.
20168 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20170 if (now < (mLastFullPssTime +
20171 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20175 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
20176 mLastFullPssTime = now;
20177 mFullPssPending = true;
20178 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20179 mPendingPssProcesses.clear();
20180 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20181 ProcessRecord app = mLruProcesses.get(i);
20182 if (app.thread == null
20183 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20186 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20187 app.pssProcState = app.setProcState;
20188 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20189 mTestPssMode, isSleepingLocked(), now);
20190 mPendingPssProcesses.add(app);
20193 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20196 public void setTestPssMode(boolean enabled) {
20197 synchronized (this) {
20198 mTestPssMode = enabled;
20200 // Whenever we enable the mode, we want to take a snapshot all of current
20201 // process mem use.
20202 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20208 * Ask a given process to GC right now.
20210 final void performAppGcLocked(ProcessRecord app) {
20212 app.lastRequestedGc = SystemClock.uptimeMillis();
20213 if (app.thread != null) {
20214 if (app.reportLowMemory) {
20215 app.reportLowMemory = false;
20216 app.thread.scheduleLowMemory();
20218 app.thread.processInBackground();
20221 } catch (Exception e) {
20227 * Returns true if things are idle enough to perform GCs.
20229 private final boolean canGcNowLocked() {
20230 boolean processingBroadcasts = false;
20231 for (BroadcastQueue q : mBroadcastQueues) {
20232 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20233 processingBroadcasts = true;
20236 return !processingBroadcasts
20237 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20241 * Perform GCs on all processes that are waiting for it, but only
20242 * if things are idle.
20244 final void performAppGcsLocked() {
20245 final int N = mProcessesToGc.size();
20249 if (canGcNowLocked()) {
20250 while (mProcessesToGc.size() > 0) {
20251 ProcessRecord proc = mProcessesToGc.remove(0);
20252 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20253 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20254 <= SystemClock.uptimeMillis()) {
20255 // To avoid spamming the system, we will GC processes one
20256 // at a time, waiting a few seconds between each.
20257 performAppGcLocked(proc);
20258 scheduleAppGcsLocked();
20261 // It hasn't been long enough since we last GCed this
20262 // process... put it in the list to wait for its time.
20263 addProcessToGcListLocked(proc);
20269 scheduleAppGcsLocked();
20274 * If all looks good, perform GCs on all processes waiting for them.
20276 final void performAppGcsIfAppropriateLocked() {
20277 if (canGcNowLocked()) {
20278 performAppGcsLocked();
20281 // Still not idle, wait some more.
20282 scheduleAppGcsLocked();
20286 * Schedule the execution of all pending app GCs.
20288 final void scheduleAppGcsLocked() {
20289 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20291 if (mProcessesToGc.size() > 0) {
20292 // Schedule a GC for the time to the next process.
20293 ProcessRecord proc = mProcessesToGc.get(0);
20294 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20296 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20297 long now = SystemClock.uptimeMillis();
20298 if (when < (now+GC_TIMEOUT)) {
20299 when = now + GC_TIMEOUT;
20301 mHandler.sendMessageAtTime(msg, when);
20306 * Add a process to the array of processes waiting to be GCed. Keeps the
20307 * list in sorted order by the last GC time. The process can't already be
20310 final void addProcessToGcListLocked(ProcessRecord proc) {
20311 boolean added = false;
20312 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20313 if (mProcessesToGc.get(i).lastRequestedGc <
20314 proc.lastRequestedGc) {
20316 mProcessesToGc.add(i+1, proc);
20321 mProcessesToGc.add(0, proc);
20326 * Set up to ask a process to GC itself. This will either do it
20327 * immediately, or put it on the list of processes to gc the next
20328 * time things are idle.
20330 final void scheduleAppGcLocked(ProcessRecord app) {
20331 long now = SystemClock.uptimeMillis();
20332 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20335 if (!mProcessesToGc.contains(app)) {
20336 addProcessToGcListLocked(app);
20337 scheduleAppGcsLocked();
20341 final void checkExcessivePowerUsageLocked(boolean doKills) {
20342 updateCpuStatsNow();
20344 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20345 boolean doWakeKills = doKills;
20346 boolean doCpuKills = doKills;
20347 if (mLastPowerCheckRealtime == 0) {
20348 doWakeKills = false;
20350 if (mLastPowerCheckUptime == 0) {
20351 doCpuKills = false;
20353 if (stats.isScreenOn()) {
20354 doWakeKills = false;
20356 final long curRealtime = SystemClock.elapsedRealtime();
20357 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20358 final long curUptime = SystemClock.uptimeMillis();
20359 final long uptimeSince = curUptime - mLastPowerCheckUptime;
20360 mLastPowerCheckRealtime = curRealtime;
20361 mLastPowerCheckUptime = curUptime;
20362 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20363 doWakeKills = false;
20365 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20366 doCpuKills = false;
20368 int i = mLruProcesses.size();
20371 ProcessRecord app = mLruProcesses.get(i);
20372 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20374 synchronized (stats) {
20375 wtime = stats.getProcessWakeTime(app.info.uid,
20376 app.pid, curRealtime);
20378 long wtimeUsed = wtime - app.lastWakeTime;
20379 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20381 StringBuilder sb = new StringBuilder(128);
20382 sb.append("Wake for ");
20383 app.toShortString(sb);
20384 sb.append(": over ");
20385 TimeUtils.formatDuration(realtimeSince, sb);
20386 sb.append(" used ");
20387 TimeUtils.formatDuration(wtimeUsed, sb);
20389 sb.append((wtimeUsed*100)/realtimeSince);
20391 Slog.i(TAG_POWER, sb.toString());
20393 sb.append("CPU for ");
20394 app.toShortString(sb);
20395 sb.append(": over ");
20396 TimeUtils.formatDuration(uptimeSince, sb);
20397 sb.append(" used ");
20398 TimeUtils.formatDuration(cputimeUsed, sb);
20400 sb.append((cputimeUsed*100)/uptimeSince);
20402 Slog.i(TAG_POWER, sb.toString());
20404 // If a process has held a wake lock for more
20405 // than 50% of the time during this period,
20406 // that sounds bad. Kill!
20407 if (doWakeKills && realtimeSince > 0
20408 && ((wtimeUsed*100)/realtimeSince) >= 50) {
20409 synchronized (stats) {
20410 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20411 realtimeSince, wtimeUsed);
20413 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20414 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20415 } else if (doCpuKills && uptimeSince > 0
20416 && ((cputimeUsed*100)/uptimeSince) >= 25) {
20417 synchronized (stats) {
20418 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20419 uptimeSince, cputimeUsed);
20421 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20422 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20424 app.lastWakeTime = wtime;
20425 app.lastCpuTime = app.curCpuTime;
20431 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20433 boolean success = true;
20435 if (app.curRawAdj != app.setRawAdj) {
20436 app.setRawAdj = app.curRawAdj;
20441 if (app.curAdj != app.setAdj) {
20442 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20443 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20444 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20446 app.setAdj = app.curAdj;
20447 app.verifiedAdj = ProcessList.INVALID_ADJ;
20450 if (app.setSchedGroup != app.curSchedGroup) {
20451 int oldSchedGroup = app.setSchedGroup;
20452 app.setSchedGroup = app.curSchedGroup;
20453 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20454 "Setting sched group of " + app.processName
20455 + " to " + app.curSchedGroup);
20456 if (app.waitingToKill != null && app.curReceiver == null
20457 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20458 app.kill(app.waitingToKill, true);
20462 switch (app.curSchedGroup) {
20463 case ProcessList.SCHED_GROUP_BACKGROUND:
20464 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20466 case ProcessList.SCHED_GROUP_TOP_APP:
20467 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20468 processGroup = Process.THREAD_GROUP_TOP_APP;
20471 processGroup = Process.THREAD_GROUP_DEFAULT;
20474 long oldId = Binder.clearCallingIdentity();
20476 Process.setProcessGroup(app.pid, processGroup);
20477 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20478 // do nothing if we already switched to RT
20479 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20480 // Switch VR thread for app to SCHED_FIFO
20481 if (mInVrMode && app.vrThreadTid != 0) {
20483 Process.setThreadScheduler(app.vrThreadTid,
20484 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20485 } catch (IllegalArgumentException e) {
20486 // thread died, ignore
20489 if (mUseFifoUiScheduling) {
20490 // Switch UI pipeline for app to SCHED_FIFO
20491 app.savedPriority = Process.getThreadPriority(app.pid);
20493 Process.setThreadScheduler(app.pid,
20494 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20495 } catch (IllegalArgumentException e) {
20496 // thread died, ignore
20498 if (app.renderThreadTid != 0) {
20500 Process.setThreadScheduler(app.renderThreadTid,
20501 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20502 } catch (IllegalArgumentException e) {
20503 // thread died, ignore
20505 if (DEBUG_OOM_ADJ) {
20506 Slog.d("UI_FIFO", "Set RenderThread (TID " +
20507 app.renderThreadTid + ") to FIFO");
20510 if (DEBUG_OOM_ADJ) {
20511 Slog.d("UI_FIFO", "Not setting RenderThread TID");
20515 // Boost priority for top app UI and render threads
20516 Process.setThreadPriority(app.pid, -10);
20517 if (app.renderThreadTid != 0) {
20519 Process.setThreadPriority(app.renderThreadTid, -10);
20520 } catch (IllegalArgumentException e) {
20521 // thread died, ignore
20526 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20527 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20528 // Reset VR thread to SCHED_OTHER
20529 // Safe to do even if we're not in VR mode
20530 if (app.vrThreadTid != 0) {
20531 Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20533 if (mUseFifoUiScheduling) {
20534 // Reset UI pipeline to SCHED_OTHER
20535 Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20536 Process.setThreadPriority(app.pid, app.savedPriority);
20537 if (app.renderThreadTid != 0) {
20538 Process.setThreadScheduler(app.renderThreadTid,
20539 Process.SCHED_OTHER, 0);
20540 Process.setThreadPriority(app.renderThreadTid, -4);
20543 // Reset priority for top app UI and render threads
20544 Process.setThreadPriority(app.pid, 0);
20545 if (app.renderThreadTid != 0) {
20546 Process.setThreadPriority(app.renderThreadTid, 0);
20550 } catch (Exception e) {
20551 Slog.w(TAG, "Failed setting process group of " + app.pid
20552 + " to " + app.curSchedGroup);
20553 e.printStackTrace();
20555 Binder.restoreCallingIdentity(oldId);
20559 if (app.repForegroundActivities != app.foregroundActivities) {
20560 app.repForegroundActivities = app.foregroundActivities;
20561 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20563 if (app.repProcState != app.curProcState) {
20564 app.repProcState = app.curProcState;
20565 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20566 if (app.thread != null) {
20569 //RuntimeException h = new RuntimeException("here");
20570 Slog.i(TAG, "Sending new process state " + app.repProcState
20571 + " to " + app /*, h*/);
20573 app.thread.setProcessState(app.repProcState);
20574 } catch (RemoteException e) {
20578 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20579 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20580 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20581 // Experimental code to more aggressively collect pss while
20582 // running test... the problem is that this tends to collect
20583 // the data right when a process is transitioning between process
20584 // states, which well tend to give noisy data.
20585 long start = SystemClock.uptimeMillis();
20586 long pss = Debug.getPss(app.pid, mTmpLong, null);
20587 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20588 mPendingPssProcesses.remove(app);
20589 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20590 + " to " + app.curProcState + ": "
20591 + (SystemClock.uptimeMillis()-start) + "ms");
20593 app.lastStateTime = now;
20594 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20595 mTestPssMode, isSleepingLocked(), now);
20596 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20597 + ProcessList.makeProcStateString(app.setProcState) + " to "
20598 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20599 + (app.nextPssTime-now) + ": " + app);
20601 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20602 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20604 requestPssLocked(app, app.setProcState);
20605 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20606 mTestPssMode, isSleepingLocked(), now);
20607 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20608 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20610 if (app.setProcState != app.curProcState) {
20611 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20612 "Proc state change of " + app.processName
20613 + " to " + app.curProcState);
20614 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20615 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20616 if (setImportant && !curImportant) {
20617 // This app is no longer something we consider important enough to allow to
20618 // use arbitrary amounts of battery power. Note
20619 // its current wake lock time to later know to kill it if
20620 // it is not behaving well.
20621 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20622 synchronized (stats) {
20623 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20624 app.pid, nowElapsed);
20626 app.lastCpuTime = app.curCpuTime;
20629 // Inform UsageStats of important process state change
20630 // Must be called before updating setProcState
20631 maybeUpdateUsageStatsLocked(app, nowElapsed);
20633 app.setProcState = app.curProcState;
20634 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20635 app.notCachedSinceIdle = false;
20638 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20640 app.procStateChanged = true;
20642 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20643 > USAGE_STATS_INTERACTION_INTERVAL) {
20644 // For apps that sit around for a long time in the interactive state, we need
20645 // to report this at least once a day so they don't go idle.
20646 maybeUpdateUsageStatsLocked(app, nowElapsed);
20649 if (changes != 0) {
20650 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20651 "Changes in " + app + ": " + changes);
20652 int i = mPendingProcessChanges.size()-1;
20653 ProcessChangeItem item = null;
20655 item = mPendingProcessChanges.get(i);
20656 if (item.pid == app.pid) {
20657 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20658 "Re-using existing item: " + item);
20664 // No existing item in pending changes; need a new one.
20665 final int NA = mAvailProcessChanges.size();
20667 item = mAvailProcessChanges.remove(NA-1);
20668 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20669 "Retrieving available item: " + item);
20671 item = new ProcessChangeItem();
20672 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20673 "Allocating new item: " + item);
20676 item.pid = app.pid;
20677 item.uid = app.info.uid;
20678 if (mPendingProcessChanges.size() == 0) {
20679 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20680 "*** Enqueueing dispatch processes changed!");
20681 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20683 mPendingProcessChanges.add(item);
20685 item.changes |= changes;
20686 item.processState = app.repProcState;
20687 item.foregroundActivities = app.repForegroundActivities;
20688 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20689 "Item " + Integer.toHexString(System.identityHashCode(item))
20690 + " " + app.toShortString() + ": changes=" + item.changes
20691 + " procState=" + item.processState
20692 + " foreground=" + item.foregroundActivities
20693 + " type=" + app.adjType + " source=" + app.adjSource
20694 + " target=" + app.adjTarget);
20700 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20701 final UidRecord.ChangeItem pendingChange;
20702 if (uidRec == null || uidRec.pendingChange == null) {
20703 if (mPendingUidChanges.size() == 0) {
20704 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20705 "*** Enqueueing dispatch uid changed!");
20706 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20708 final int NA = mAvailUidChanges.size();
20710 pendingChange = mAvailUidChanges.remove(NA-1);
20711 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20712 "Retrieving available item: " + pendingChange);
20714 pendingChange = new UidRecord.ChangeItem();
20715 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20716 "Allocating new item: " + pendingChange);
20718 if (uidRec != null) {
20719 uidRec.pendingChange = pendingChange;
20720 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20721 // If this uid is going away, and we haven't yet reported it is gone,
20723 change = UidRecord.CHANGE_GONE_IDLE;
20725 } else if (uid < 0) {
20726 throw new IllegalArgumentException("No UidRecord or uid");
20728 pendingChange.uidRecord = uidRec;
20729 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20730 mPendingUidChanges.add(pendingChange);
20732 pendingChange = uidRec.pendingChange;
20733 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20734 change = UidRecord.CHANGE_GONE_IDLE;
20737 pendingChange.change = change;
20738 pendingChange.processState = uidRec != null
20739 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20742 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20743 String authority) {
20744 if (app == null) return;
20745 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20746 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20747 if (userState == null) return;
20748 final long now = SystemClock.elapsedRealtime();
20749 Long lastReported = userState.mProviderLastReportedFg.get(authority);
20750 if (lastReported == null || lastReported < now - 60 * 1000L) {
20751 if (mSystemReady) {
20752 // Cannot touch the user stats if not system ready
20753 mUsageStatsService.reportContentProviderUsage(
20754 authority, providerPkgName, app.userId);
20756 userState.mProviderLastReportedFg.put(authority, now);
20761 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20762 if (DEBUG_USAGE_STATS) {
20763 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20764 + "] state changes: old = " + app.setProcState + ", new = "
20765 + app.curProcState);
20767 if (mUsageStatsService == null) {
20770 boolean isInteraction;
20771 // To avoid some abuse patterns, we are going to be careful about what we consider
20772 // to be an app interaction. Being the top activity doesn't count while the display
20773 // is sleeping, nor do short foreground services.
20774 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20775 isInteraction = true;
20776 app.fgInteractionTime = 0;
20777 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20778 if (app.fgInteractionTime == 0) {
20779 app.fgInteractionTime = nowElapsed;
20780 isInteraction = false;
20782 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20785 // If the app was being forced to the foreground, by say a Toast, then
20786 // no need to treat it as an interaction
20787 isInteraction = app.forcingToForeground == null
20788 && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20789 app.fgInteractionTime = 0;
20791 if (isInteraction && (!app.reportedInteraction
20792 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20793 app.interactionEventTime = nowElapsed;
20794 String[] packages = app.getPackageList();
20795 if (packages != null) {
20796 for (int i = 0; i < packages.length; i++) {
20797 mUsageStatsService.reportEvent(packages[i], app.userId,
20798 UsageEvents.Event.SYSTEM_INTERACTION);
20802 app.reportedInteraction = isInteraction;
20803 if (!isInteraction) {
20804 app.interactionEventTime = 0;
20808 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20809 if (proc.thread != null) {
20810 if (proc.baseProcessTracker != null) {
20811 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20816 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20817 ProcessRecord TOP_APP, boolean doingAll, long now) {
20818 if (app.thread == null) {
20822 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20824 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20827 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20829 if (isForeground != proc.foregroundServices) {
20830 proc.foregroundServices = isForeground;
20831 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20833 if (isForeground) {
20834 if (curProcs == null) {
20835 curProcs = new ArrayList<ProcessRecord>();
20836 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20838 if (!curProcs.contains(proc)) {
20839 curProcs.add(proc);
20840 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20841 proc.info.packageName, proc.info.uid);
20844 if (curProcs != null) {
20845 if (curProcs.remove(proc)) {
20846 mBatteryStatsService.noteEvent(
20847 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20848 proc.info.packageName, proc.info.uid);
20849 if (curProcs.size() <= 0) {
20850 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20856 updateOomAdjLocked();
20861 private final ActivityRecord resumedAppLocked() {
20862 ActivityRecord act = mStackSupervisor.resumedAppLocked();
20866 pkg = act.packageName;
20867 uid = act.info.applicationInfo.uid;
20872 // Has the UID or resumed package name changed?
20873 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20874 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20875 if (mCurResumedPackage != null) {
20876 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20877 mCurResumedPackage, mCurResumedUid);
20879 mCurResumedPackage = pkg;
20880 mCurResumedUid = uid;
20881 if (mCurResumedPackage != null) {
20882 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20883 mCurResumedPackage, mCurResumedUid);
20889 final boolean updateOomAdjLocked(ProcessRecord app) {
20890 final ActivityRecord TOP_ACT = resumedAppLocked();
20891 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20892 final boolean wasCached = app.cached;
20896 // This is the desired cached adjusment we want to tell it to use.
20897 // If our app is currently cached, we know it, and that is it. Otherwise,
20898 // we don't know it yet, and it needs to now be cached we will then
20899 // need to do a complete oom adj.
20900 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20901 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20902 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20903 SystemClock.uptimeMillis());
20904 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20905 // Changed to/from cached state, so apps after it in the LRU
20906 // list may also be changed.
20907 updateOomAdjLocked();
20912 final void updateOomAdjLocked() {
20913 final ActivityRecord TOP_ACT = resumedAppLocked();
20914 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20915 final long now = SystemClock.uptimeMillis();
20916 final long nowElapsed = SystemClock.elapsedRealtime();
20917 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20918 final int N = mLruProcesses.size();
20921 RuntimeException e = new RuntimeException();
20922 e.fillInStackTrace();
20923 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20926 // Reset state in all uid records.
20927 for (int i=mActiveUids.size()-1; i>=0; i--) {
20928 final UidRecord uidRec = mActiveUids.valueAt(i);
20929 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20930 "Starting update of " + uidRec);
20934 mStackSupervisor.rankTaskLayersIfNeeded();
20937 mNewNumServiceProcs = 0;
20938 mNewNumAServiceProcs = 0;
20940 final int emptyProcessLimit;
20941 final int cachedProcessLimit;
20942 if (mProcessLimit <= 0) {
20943 emptyProcessLimit = cachedProcessLimit = 0;
20944 } else if (mProcessLimit == 1) {
20945 emptyProcessLimit = 1;
20946 cachedProcessLimit = 0;
20948 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20949 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20952 // Let's determine how many processes we have running vs.
20953 // how many slots we have for background processes; we may want
20954 // to put multiple processes in a slot of there are enough of
20956 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20957 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20958 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20959 if (numEmptyProcs > cachedProcessLimit) {
20960 // If there are more empty processes than our limit on cached
20961 // processes, then use the cached process limit for the factor.
20962 // This ensures that the really old empty processes get pushed
20963 // down to the bottom, so if we are running low on memory we will
20964 // have a better chance at keeping around more cached processes
20965 // instead of a gazillion empty processes.
20966 numEmptyProcs = cachedProcessLimit;
20968 int emptyFactor = numEmptyProcs/numSlots;
20969 if (emptyFactor < 1) emptyFactor = 1;
20970 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20971 if (cachedFactor < 1) cachedFactor = 1;
20972 int stepCached = 0;
20976 int numTrimming = 0;
20978 mNumNonCachedProcs = 0;
20979 mNumCachedHiddenProcs = 0;
20981 // First update the OOM adjustment for each of the
20982 // application processes based on their current state.
20983 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20984 int nextCachedAdj = curCachedAdj+1;
20985 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20986 int nextEmptyAdj = curEmptyAdj+2;
20987 for (int i=N-1; i>=0; i--) {
20988 ProcessRecord app = mLruProcesses.get(i);
20992 if (!app.killedByAm && app.thread != null) {
20993 app.procStateChanged = false;
20994 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20996 // If we haven't yet assigned the final cached adj
20997 // to the process, do that now.
20998 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20999 switch (app.curProcState) {
21000 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21001 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21002 // This process is a cached process holding activities...
21003 // assign it the next cached value for that type, and then
21004 // step that cached level.
21005 app.curRawAdj = curCachedAdj;
21006 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21007 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21008 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21010 if (curCachedAdj != nextCachedAdj) {
21012 if (stepCached >= cachedFactor) {
21014 curCachedAdj = nextCachedAdj;
21015 nextCachedAdj += 2;
21016 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21017 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21023 // For everything else, assign next empty cached process
21024 // level and bump that up. Note that this means that
21025 // long-running services that have dropped down to the
21026 // cached level will be treated as empty (since their process
21027 // state is still as a service), which is what we want.
21028 app.curRawAdj = curEmptyAdj;
21029 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21030 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21031 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21033 if (curEmptyAdj != nextEmptyAdj) {
21035 if (stepEmpty >= emptyFactor) {
21037 curEmptyAdj = nextEmptyAdj;
21039 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21040 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21048 applyOomAdjLocked(app, true, now, nowElapsed);
21050 // Count the number of process types.
21051 switch (app.curProcState) {
21052 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21053 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21054 mNumCachedHiddenProcs++;
21056 if (numCached > cachedProcessLimit) {
21057 app.kill("cached #" + numCached, true);
21060 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21061 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21062 && app.lastActivityTime < oldTime) {
21063 app.kill("empty for "
21064 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21065 / 1000) + "s", true);
21068 if (numEmpty > emptyProcessLimit) {
21069 app.kill("empty #" + numEmpty, true);
21074 mNumNonCachedProcs++;
21078 if (app.isolated && app.services.size() <= 0) {
21079 // If this is an isolated process, and there are no
21080 // services running in it, then the process is no longer
21081 // needed. We agressively kill these because we can by
21082 // definition not re-use the same process again, and it is
21083 // good to avoid having whatever code was running in them
21084 // left sitting around after no longer needed.
21085 app.kill("isolated not needed", true);
21087 // Keeping this process, update its uid.
21088 final UidRecord uidRec = app.uidRecord;
21089 if (uidRec != null && uidRec.curProcState > app.curProcState) {
21090 uidRec.curProcState = app.curProcState;
21094 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21095 && !app.killedByAm) {
21101 mNumServiceProcs = mNewNumServiceProcs;
21103 // Now determine the memory trimming level of background processes.
21104 // Unfortunately we need to start at the back of the list to do this
21105 // properly. We only do this if the number of background apps we
21106 // are managing to keep around is less than half the maximum we desire;
21107 // if we are keeping a good number around, we'll let them use whatever
21108 // memory they want.
21109 final int numCachedAndEmpty = numCached + numEmpty;
21111 if (numCached <= ProcessList.TRIM_CACHED_APPS
21112 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21113 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21114 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21115 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21116 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21118 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21121 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21123 // We always allow the memory level to go up (better). We only allow it to go
21124 // down if we are in a state where that is allowed, *and* the total number of processes
21125 // has gone down since last time.
21126 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21127 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21128 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21129 if (memFactor > mLastMemoryLevel) {
21130 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21131 memFactor = mLastMemoryLevel;
21132 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21135 if (memFactor != mLastMemoryLevel) {
21136 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21138 mLastMemoryLevel = memFactor;
21139 mLastNumProcesses = mLruProcesses.size();
21140 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21141 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21142 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21143 if (mLowRamStartTime == 0) {
21144 mLowRamStartTime = now;
21148 switch (memFactor) {
21149 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21150 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21152 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21153 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21156 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21159 int factor = numTrimming/3;
21161 if (mHomeProcess != null) minFactor++;
21162 if (mPreviousProcess != null) minFactor++;
21163 if (factor < minFactor) factor = minFactor;
21164 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21165 for (int i=N-1; i>=0; i--) {
21166 ProcessRecord app = mLruProcesses.get(i);
21170 if (allChanged || app.procStateChanged) {
21171 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21172 app.procStateChanged = false;
21174 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21175 && !app.killedByAm) {
21176 if (app.trimMemoryLevel < curLevel && app.thread != null) {
21178 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21179 "Trimming memory of " + app.processName + " to " + curLevel);
21180 app.thread.scheduleTrimMemory(curLevel);
21181 } catch (RemoteException e) {
21184 // For now we won't do this; our memory trimming seems
21185 // to be good enough at this point that destroying
21186 // activities causes more harm than good.
21187 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21188 && app != mHomeProcess && app != mPreviousProcess) {
21189 // Need to do this on its own message because the stack may not
21190 // be in a consistent state at this point.
21191 // For these apps we will also finish their activities
21192 // to help them free memory.
21193 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21197 app.trimMemoryLevel = curLevel;
21199 if (step >= factor) {
21201 switch (curLevel) {
21202 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21203 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21205 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21206 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21210 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21211 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21212 && app.thread != null) {
21214 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21215 "Trimming memory of heavy-weight " + app.processName
21216 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21217 app.thread.scheduleTrimMemory(
21218 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21219 } catch (RemoteException e) {
21222 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21224 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21225 || app.systemNoUi) && app.pendingUiClean) {
21226 // If this application is now in the background and it
21227 // had done UI, then give it the special trim level to
21228 // have it free UI resources.
21229 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21230 if (app.trimMemoryLevel < level && app.thread != null) {
21232 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21233 "Trimming memory of bg-ui " + app.processName
21235 app.thread.scheduleTrimMemory(level);
21236 } catch (RemoteException e) {
21239 app.pendingUiClean = false;
21241 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21243 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21244 "Trimming memory of fg " + app.processName
21245 + " to " + fgTrimLevel);
21246 app.thread.scheduleTrimMemory(fgTrimLevel);
21247 } catch (RemoteException e) {
21250 app.trimMemoryLevel = fgTrimLevel;
21254 if (mLowRamStartTime != 0) {
21255 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21256 mLowRamStartTime = 0;
21258 for (int i=N-1; i>=0; i--) {
21259 ProcessRecord app = mLruProcesses.get(i);
21260 if (allChanged || app.procStateChanged) {
21261 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21262 app.procStateChanged = false;
21264 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21265 || app.systemNoUi) && app.pendingUiClean) {
21266 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21267 && app.thread != null) {
21269 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21270 "Trimming memory of ui hidden " + app.processName
21271 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21272 app.thread.scheduleTrimMemory(
21273 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21274 } catch (RemoteException e) {
21277 app.pendingUiClean = false;
21279 app.trimMemoryLevel = 0;
21283 if (mAlwaysFinishActivities) {
21284 // Need to do this on its own message because the stack may not
21285 // be in a consistent state at this point.
21286 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21290 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21293 // Update from any uid changes.
21294 for (int i=mActiveUids.size()-1; i>=0; i--) {
21295 final UidRecord uidRec = mActiveUids.valueAt(i);
21296 int uidChange = UidRecord.CHANGE_PROCSTATE;
21297 if (uidRec.setProcState != uidRec.curProcState) {
21298 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21299 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21300 + " to " + uidRec.curProcState);
21301 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21302 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21303 uidRec.lastBackgroundTime = nowElapsed;
21304 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21305 // Note: the background settle time is in elapsed realtime, while
21306 // the handler time base is uptime. All this means is that we may
21307 // stop background uids later than we had intended, but that only
21308 // happens because the device was sleeping so we are okay anyway.
21309 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21314 uidChange = UidRecord.CHANGE_ACTIVE;
21315 uidRec.idle = false;
21317 uidRec.lastBackgroundTime = 0;
21319 uidRec.setProcState = uidRec.curProcState;
21320 enqueueUidChangeLocked(uidRec, -1, uidChange);
21321 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21325 if (mProcessStats.shouldWriteNowLocked(now)) {
21326 mHandler.post(new Runnable() {
21327 @Override public void run() {
21328 synchronized (ActivityManagerService.this) {
21329 mProcessStats.writeStateAsyncLocked();
21335 if (DEBUG_OOM_ADJ) {
21336 final long duration = SystemClock.uptimeMillis() - now;
21338 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21339 new RuntimeException("here").fillInStackTrace());
21341 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21346 final void idleUids() {
21347 synchronized (this) {
21348 final long nowElapsed = SystemClock.elapsedRealtime();
21349 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21351 for (int i=mActiveUids.size()-1; i>=0; i--) {
21352 final UidRecord uidRec = mActiveUids.valueAt(i);
21353 final long bgTime = uidRec.lastBackgroundTime;
21354 if (bgTime > 0 && !uidRec.idle) {
21355 if (bgTime <= maxBgTime) {
21356 uidRec.idle = true;
21357 doStopUidLocked(uidRec.uid, uidRec);
21359 if (nextTime == 0 || nextTime > bgTime) {
21365 if (nextTime > 0) {
21366 mHandler.removeMessages(IDLE_UIDS_MSG);
21367 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21368 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21373 final void runInBackgroundDisabled(int uid) {
21374 synchronized (this) {
21375 UidRecord uidRec = mActiveUids.get(uid);
21376 if (uidRec != null) {
21377 // This uid is actually running... should it be considered background now?
21379 doStopUidLocked(uidRec.uid, uidRec);
21382 // This uid isn't actually running... still send a report about it being "stopped".
21383 doStopUidLocked(uid, null);
21388 final void doStopUidLocked(int uid, final UidRecord uidRec) {
21389 mServices.stopInBackgroundLocked(uid);
21390 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21393 final void trimApplications() {
21394 synchronized (this) {
21397 // First remove any unused application processes whose package
21398 // has been removed.
21399 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21400 final ProcessRecord app = mRemovedProcesses.get(i);
21401 if (app.activities.size() == 0
21402 && app.curReceiver == null && app.services.size() == 0) {
21404 TAG, "Exiting empty application process "
21405 + app.toShortString() + " ("
21406 + (app.thread != null ? app.thread.asBinder() : null)
21408 if (app.pid > 0 && app.pid != MY_PID) {
21409 app.kill("empty", false);
21412 app.thread.scheduleExit();
21413 } catch (Exception e) {
21414 // Ignore exceptions.
21417 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21418 mRemovedProcesses.remove(i);
21420 if (app.persistent) {
21421 addAppLocked(app.info, false, null /* ABI override */);
21426 // Now update the oom adj for all processes.
21427 updateOomAdjLocked();
21431 /** This method sends the specified signal to each of the persistent apps */
21432 public void signalPersistentProcesses(int sig) throws RemoteException {
21433 if (sig != Process.SIGNAL_USR1) {
21434 throw new SecurityException("Only SIGNAL_USR1 is allowed");
21437 synchronized (this) {
21438 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21439 != PackageManager.PERMISSION_GRANTED) {
21440 throw new SecurityException("Requires permission "
21441 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21444 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21445 ProcessRecord r = mLruProcesses.get(i);
21446 if (r.thread != null && r.persistent) {
21447 Process.sendSignal(r.pid, sig);
21453 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21454 if (proc == null || proc == mProfileProc) {
21455 proc = mProfileProc;
21456 profileType = mProfileType;
21457 clearProfilerLocked();
21459 if (proc == null) {
21463 proc.thread.profilerControl(false, null, profileType);
21464 } catch (RemoteException e) {
21465 throw new IllegalStateException("Process disappeared");
21469 private void clearProfilerLocked() {
21470 if (mProfileFd != null) {
21472 mProfileFd.close();
21473 } catch (IOException e) {
21476 mProfileApp = null;
21477 mProfileProc = null;
21478 mProfileFile = null;
21480 mAutoStopProfiler = false;
21481 mSamplingInterval = 0;
21484 public boolean profileControl(String process, int userId, boolean start,
21485 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21488 synchronized (this) {
21489 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21490 // its own permission.
21491 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21492 != PackageManager.PERMISSION_GRANTED) {
21493 throw new SecurityException("Requires permission "
21494 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21497 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21498 throw new IllegalArgumentException("null profile info or fd");
21501 ProcessRecord proc = null;
21502 if (process != null) {
21503 proc = findProcessLocked(process, userId, "profileControl");
21506 if (start && (proc == null || proc.thread == null)) {
21507 throw new IllegalArgumentException("Unknown process: " + process);
21511 stopProfilerLocked(null, 0);
21512 setProfileApp(proc.info, proc.processName, profilerInfo);
21513 mProfileProc = proc;
21514 mProfileType = profileType;
21515 ParcelFileDescriptor fd = profilerInfo.profileFd;
21518 } catch (IOException e) {
21521 profilerInfo.profileFd = fd;
21522 proc.thread.profilerControl(start, profilerInfo, profileType);
21526 stopProfilerLocked(proc, profileType);
21527 if (profilerInfo != null && profilerInfo.profileFd != null) {
21529 profilerInfo.profileFd.close();
21530 } catch (IOException e) {
21537 } catch (RemoteException e) {
21538 throw new IllegalStateException("Process disappeared");
21540 if (profilerInfo != null && profilerInfo.profileFd != null) {
21542 profilerInfo.profileFd.close();
21543 } catch (IOException e) {
21549 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21550 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21551 userId, true, ALLOW_FULL_ONLY, callName, null);
21552 ProcessRecord proc = null;
21554 int pid = Integer.parseInt(process);
21555 synchronized (mPidsSelfLocked) {
21556 proc = mPidsSelfLocked.get(pid);
21558 } catch (NumberFormatException e) {
21561 if (proc == null) {
21562 ArrayMap<String, SparseArray<ProcessRecord>> all
21563 = mProcessNames.getMap();
21564 SparseArray<ProcessRecord> procs = all.get(process);
21565 if (procs != null && procs.size() > 0) {
21566 proc = procs.valueAt(0);
21567 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21568 for (int i=1; i<procs.size(); i++) {
21569 ProcessRecord thisProc = procs.valueAt(i);
21570 if (thisProc.userId == userId) {
21582 public boolean dumpHeap(String process, int userId, boolean managed,
21583 String path, ParcelFileDescriptor fd) throws RemoteException {
21586 synchronized (this) {
21587 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21588 // its own permission (same as profileControl).
21589 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21590 != PackageManager.PERMISSION_GRANTED) {
21591 throw new SecurityException("Requires permission "
21592 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21596 throw new IllegalArgumentException("null fd");
21599 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21600 if (proc == null || proc.thread == null) {
21601 throw new IllegalArgumentException("Unknown process: " + process);
21604 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21605 if (!isDebuggable) {
21606 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21607 throw new SecurityException("Process not debuggable: " + proc);
21611 proc.thread.dumpHeap(managed, path, fd);
21615 } catch (RemoteException e) {
21616 throw new IllegalStateException("Process disappeared");
21621 } catch (IOException e) {
21628 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21629 String reportPackage) {
21630 if (processName != null) {
21631 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21632 "setDumpHeapDebugLimit()");
21634 synchronized (mPidsSelfLocked) {
21635 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21636 if (proc == null) {
21637 throw new SecurityException("No process found for calling pid "
21638 + Binder.getCallingPid());
21640 if (!Build.IS_DEBUGGABLE
21641 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21642 throw new SecurityException("Not running a debuggable build");
21644 processName = proc.processName;
21646 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21647 throw new SecurityException("Package " + reportPackage + " is not running in "
21652 synchronized (this) {
21653 if (maxMemSize > 0) {
21654 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21657 mMemWatchProcesses.remove(processName, uid);
21659 mMemWatchProcesses.getMap().remove(processName);
21666 public void dumpHeapFinished(String path) {
21667 synchronized (this) {
21668 if (Binder.getCallingPid() != mMemWatchDumpPid) {
21669 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21670 + " does not match last pid " + mMemWatchDumpPid);
21673 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21674 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21675 + " does not match last path " + mMemWatchDumpFile);
21678 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21679 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21683 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21684 public void monitor() {
21685 synchronized (this) { }
21688 void onCoreSettingsChange(Bundle settings) {
21689 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21690 ProcessRecord processRecord = mLruProcesses.get(i);
21692 if (processRecord.thread != null) {
21693 processRecord.thread.setCoreSettings(settings);
21695 } catch (RemoteException re) {
21701 // Multi-user methods
21704 * Start user, if its not already running, but don't bring it to foreground.
21707 public boolean startUserInBackground(final int userId) {
21708 return mUserController.startUser(userId, /* foreground */ false);
21712 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21713 return mUserController.unlockUser(userId, token, secret, listener);
21717 public boolean switchUser(final int targetUserId) {
21718 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21719 UserInfo currentUserInfo;
21720 UserInfo targetUserInfo;
21721 synchronized (this) {
21722 int currentUserId = mUserController.getCurrentUserIdLocked();
21723 currentUserInfo = mUserController.getUserInfo(currentUserId);
21724 targetUserInfo = mUserController.getUserInfo(targetUserId);
21725 if (targetUserInfo == null) {
21726 Slog.w(TAG, "No user info for user #" + targetUserId);
21729 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21730 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21731 + " when device is in demo mode");
21734 if (!targetUserInfo.supportsSwitchTo()) {
21735 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21738 if (targetUserInfo.isManagedProfile()) {
21739 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21742 mUserController.setTargetUserIdLocked(targetUserId);
21744 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21745 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21746 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21750 void scheduleStartProfilesLocked() {
21751 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21752 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21753 DateUtils.SECOND_IN_MILLIS);
21758 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21759 return mUserController.stopUser(userId, force, callback);
21763 public UserInfo getCurrentUser() {
21764 return mUserController.getCurrentUser();
21768 public boolean isUserRunning(int userId, int flags) {
21769 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21770 && checkCallingPermission(INTERACT_ACROSS_USERS)
21771 != PackageManager.PERMISSION_GRANTED) {
21772 String msg = "Permission Denial: isUserRunning() from pid="
21773 + Binder.getCallingPid()
21774 + ", uid=" + Binder.getCallingUid()
21775 + " requires " + INTERACT_ACROSS_USERS;
21777 throw new SecurityException(msg);
21779 synchronized (this) {
21780 return mUserController.isUserRunningLocked(userId, flags);
21785 public int[] getRunningUserIds() {
21786 if (checkCallingPermission(INTERACT_ACROSS_USERS)
21787 != PackageManager.PERMISSION_GRANTED) {
21788 String msg = "Permission Denial: isUserRunning() from pid="
21789 + Binder.getCallingPid()
21790 + ", uid=" + Binder.getCallingUid()
21791 + " requires " + INTERACT_ACROSS_USERS;
21793 throw new SecurityException(msg);
21795 synchronized (this) {
21796 return mUserController.getStartedUserArrayLocked();
21801 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21802 mUserController.registerUserSwitchObserver(observer, name);
21806 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21807 mUserController.unregisterUserSwitchObserver(observer);
21810 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21811 if (info == null) return null;
21812 ApplicationInfo newInfo = new ApplicationInfo(info);
21813 newInfo.initForUser(userId);
21817 public boolean isUserStopped(int userId) {
21818 synchronized (this) {
21819 return mUserController.getStartedUserStateLocked(userId) == null;
21823 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21825 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21829 ActivityInfo info = new ActivityInfo(aInfo);
21830 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21834 private boolean processSanityChecksLocked(ProcessRecord process) {
21835 if (process == null || process.thread == null) {
21839 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21840 if (!isDebuggable) {
21841 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21849 public boolean startBinderTracking() throws RemoteException {
21850 synchronized (this) {
21851 mBinderTransactionTrackingEnabled = true;
21852 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21853 // permission (same as profileControl).
21854 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21855 != PackageManager.PERMISSION_GRANTED) {
21856 throw new SecurityException("Requires permission "
21857 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21860 for (int i = 0; i < mLruProcesses.size(); i++) {
21861 ProcessRecord process = mLruProcesses.get(i);
21862 if (!processSanityChecksLocked(process)) {
21866 process.thread.startBinderTracking();
21867 } catch (RemoteException e) {
21868 Log.v(TAG, "Process disappared");
21875 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21877 synchronized (this) {
21878 mBinderTransactionTrackingEnabled = false;
21879 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21880 // permission (same as profileControl).
21881 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21882 != PackageManager.PERMISSION_GRANTED) {
21883 throw new SecurityException("Requires permission "
21884 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21888 throw new IllegalArgumentException("null fd");
21891 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21892 pw.println("Binder transaction traces for all processes.\n");
21893 for (ProcessRecord process : mLruProcesses) {
21894 if (!processSanityChecksLocked(process)) {
21898 pw.println("Traces for process: " + process.processName);
21901 TransferPipe tp = new TransferPipe();
21903 process.thread.stopBinderTrackingAndDump(
21904 tp.getWriteFd().getFileDescriptor());
21905 tp.go(fd.getFileDescriptor());
21909 } catch (IOException e) {
21910 pw.println("Failure while dumping IPC traces from " + process +
21911 ". Exception: " + e);
21913 } catch (RemoteException e) {
21914 pw.println("Got a RemoteException while dumping IPC traces from " +
21915 process + ". Exception: " + e);
21926 } catch (IOException e) {
21932 private final class LocalService extends ActivityManagerInternal {
21934 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
21935 int targetUserId) {
21936 synchronized (ActivityManagerService.this) {
21937 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
21938 targetPkg, intent, null, targetUserId);
21943 public String checkContentProviderAccess(String authority, int userId) {
21944 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21948 public void onWakefulnessChanged(int wakefulness) {
21949 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21953 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21954 String processName, String abiOverride, int uid, Runnable crashHandler) {
21955 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21956 processName, abiOverride, uid, crashHandler);
21960 public SleepToken acquireSleepToken(String tag) {
21961 Preconditions.checkNotNull(tag);
21963 synchronized (ActivityManagerService.this) {
21964 SleepTokenImpl token = new SleepTokenImpl(tag);
21965 mSleepTokens.add(token);
21966 updateSleepIfNeededLocked();
21972 public ComponentName getHomeActivityForUser(int userId) {
21973 synchronized (ActivityManagerService.this) {
21974 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21975 return homeActivity == null ? null : homeActivity.realActivity;
21980 public void onUserRemoved(int userId) {
21981 synchronized (ActivityManagerService.this) {
21982 ActivityManagerService.this.onUserStoppedLocked(userId);
21987 public void onLocalVoiceInteractionStarted(IBinder activity,
21988 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21989 synchronized (ActivityManagerService.this) {
21990 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21991 voiceSession, voiceInteractor);
21996 public void notifyStartingWindowDrawn() {
21997 synchronized (ActivityManagerService.this) {
21998 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22003 public void notifyAppTransitionStarting(int reason) {
22004 synchronized (ActivityManagerService.this) {
22005 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22010 public void notifyAppTransitionFinished() {
22011 synchronized (ActivityManagerService.this) {
22012 mStackSupervisor.notifyAppTransitionDone();
22017 public void notifyAppTransitionCancelled() {
22018 synchronized (ActivityManagerService.this) {
22019 mStackSupervisor.notifyAppTransitionDone();
22024 public List<IBinder> getTopVisibleActivities() {
22025 synchronized (ActivityManagerService.this) {
22026 return mStackSupervisor.getTopVisibleActivities();
22031 public void notifyDockedStackMinimizedChanged(boolean minimized) {
22032 synchronized (ActivityManagerService.this) {
22033 mStackSupervisor.setDockedStackMinimized(minimized);
22038 public void killForegroundAppsForUser(int userHandle) {
22039 synchronized (ActivityManagerService.this) {
22040 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22041 final int NP = mProcessNames.getMap().size();
22042 for (int ip = 0; ip < NP; ip++) {
22043 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22044 final int NA = apps.size();
22045 for (int ia = 0; ia < NA; ia++) {
22046 final ProcessRecord app = apps.valueAt(ia);
22047 if (app.persistent) {
22048 // We don't kill persistent processes.
22053 } else if (app.userId == userHandle && app.foregroundActivities) {
22054 app.removed = true;
22060 final int N = procs.size();
22061 for (int i = 0; i < N; i++) {
22062 removeProcessLocked(procs.get(i), false, true, "kill all fg");
22068 public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22069 if (!(target instanceof PendingIntentRecord)) {
22070 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22073 ((PendingIntentRecord) target).setWhitelistDuration(duration);
22077 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22079 Preconditions.checkNotNull(values, "Configuration must not be null");
22080 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22081 synchronized (ActivityManagerService.this) {
22082 updateConfigurationLocked(values, null, false, true, userId,
22083 false /* deferResume */);
22088 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22090 Preconditions.checkNotNull(intents, "intents");
22091 final String[] resolvedTypes = new String[intents.length];
22092 for (int i = 0; i < intents.length; i++) {
22093 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22096 // UID of the package on user userId.
22097 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22098 // packageUid may not be initialized.
22099 int packageUid = 0;
22101 packageUid = AppGlobals.getPackageManager().getPackageUid(
22102 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22103 } catch (RemoteException e) {
22104 // Shouldn't happen.
22107 synchronized (ActivityManagerService.this) {
22108 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22109 /*resultTo*/ null, bOptions, userId);
22114 public int getUidProcessState(int uid) {
22115 return getUidState(uid);
22119 private final class SleepTokenImpl extends SleepToken {
22120 private final String mTag;
22121 private final long mAcquireTime;
22123 public SleepTokenImpl(String tag) {
22125 mAcquireTime = SystemClock.uptimeMillis();
22129 public void release() {
22130 synchronized (ActivityManagerService.this) {
22131 if (mSleepTokens.remove(this)) {
22132 updateSleepIfNeededLocked();
22138 public String toString() {
22139 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22144 * An implementation of IAppTask, that allows an app to manage its own tasks via
22145 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
22146 * only the process that calls getAppTasks() can call the AppTask methods.
22148 class AppTaskImpl extends IAppTask.Stub {
22149 private int mTaskId;
22150 private int mCallingUid;
22152 public AppTaskImpl(int taskId, int callingUid) {
22154 mCallingUid = callingUid;
22157 private void checkCaller() {
22158 if (mCallingUid != Binder.getCallingUid()) {
22159 throw new SecurityException("Caller " + mCallingUid
22160 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22165 public void finishAndRemoveTask() {
22168 synchronized (ActivityManagerService.this) {
22169 long origId = Binder.clearCallingIdentity();
22171 // We remove the task from recents to preserve backwards
22172 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22173 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22176 Binder.restoreCallingIdentity(origId);
22182 public ActivityManager.RecentTaskInfo getTaskInfo() {
22185 synchronized (ActivityManagerService.this) {
22186 long origId = Binder.clearCallingIdentity();
22188 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22190 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22192 return createRecentTaskInfoFromTaskRecord(tr);
22194 Binder.restoreCallingIdentity(origId);
22200 public void moveToFront() {
22202 // Will bring task to front if it already has a root activity.
22203 final long origId = Binder.clearCallingIdentity();
22205 synchronized (this) {
22206 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22209 Binder.restoreCallingIdentity(origId);
22214 public int startActivity(IBinder whoThread, String callingPackage,
22215 Intent intent, String resolvedType, Bundle bOptions) {
22218 int callingUser = UserHandle.getCallingUserId();
22220 IApplicationThread appThread;
22221 synchronized (ActivityManagerService.this) {
22222 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22224 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22226 appThread = ApplicationThreadNative.asInterface(whoThread);
22227 if (appThread == null) {
22228 throw new IllegalArgumentException("Bad app thread " + appThread);
22231 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22232 resolvedType, null, null, null, null, 0, 0, null, null,
22233 null, bOptions, false, callingUser, null, tr);
22237 public void setExcludeFromRecents(boolean exclude) {
22240 synchronized (ActivityManagerService.this) {
22241 long origId = Binder.clearCallingIdentity();
22243 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22245 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22247 Intent intent = tr.getBaseIntent();
22249 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22251 intent.setFlags(intent.getFlags()
22252 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22255 Binder.restoreCallingIdentity(origId);
22262 * Kill processes for the user with id userId and that depend on the package named packageName
22265 public void killPackageDependents(String packageName, int userId) {
22266 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22267 if (packageName == null) {
22268 throw new NullPointerException(
22269 "Cannot kill the dependents of a package without its name.");
22272 long callingId = Binder.clearCallingIdentity();
22273 IPackageManager pm = AppGlobals.getPackageManager();
22276 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22277 } catch (RemoteException e) {
22279 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22280 throw new IllegalArgumentException(
22281 "Cannot kill dependents of non-existing package " + packageName);
22284 synchronized(this) {
22285 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22286 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22287 "dep: " + packageName);
22290 Binder.restoreCallingIdentity(callingId);
22295 public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22296 final int userId = intent.getCreatorUserHandle().getIdentifier();
22297 if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22300 IIntentSender target = intent.getTarget();
22301 if (!(target instanceof PendingIntentRecord)) {
22304 final PendingIntentRecord record = (PendingIntentRecord) target;
22305 final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22306 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22307 // For direct boot aware activities, they can be shown without triggering a work challenge
22308 // before the profile user is unlocked.
22309 return rInfo != null && rInfo.activityInfo != null;