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 private boolean mSleeping = false;
1219 * The process state used for processes that are running the top activities.
1220 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1222 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1225 * Set while we are running a voice interaction. This overrides
1226 * sleeping while it is active.
1228 private IVoiceInteractionSession mRunningVoice;
1231 * For some direct access we need to power manager.
1233 PowerManagerInternal mLocalPowerManager;
1236 * We want to hold a wake lock while running a voice interaction session, since
1237 * this may happen with the screen off and we need to keep the CPU running to
1238 * be able to continue to interact with the user.
1240 PowerManager.WakeLock mVoiceWakeLock;
1243 * State of external calls telling us if the device is awake or asleep.
1245 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1248 * A list of tokens that cause the top activity to be put to sleep.
1249 * They are used by components that may hide and block interaction with underlying
1252 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1254 static final int LOCK_SCREEN_HIDDEN = 0;
1255 static final int LOCK_SCREEN_LEAVING = 1;
1256 static final int LOCK_SCREEN_SHOWN = 2;
1258 * State of external call telling us if the lock screen is shown.
1260 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1263 * Set if we are shutting down the system, similar to sleeping.
1265 boolean mShuttingDown = false;
1268 * Current sequence id for oom_adj computation traversal.
1273 * Current sequence id for process LRU updating.
1278 * Keep track of the non-cached/empty process we last found, to help
1279 * determine how to distribute cached/empty processes next time.
1281 int mNumNonCachedProcs = 0;
1284 * Keep track of the number of cached hidden procs, to balance oom adj
1285 * distribution between those and empty procs.
1287 int mNumCachedHiddenProcs = 0;
1290 * Keep track of the number of service processes we last found, to
1291 * determine on the next iteration which should be B services.
1293 int mNumServiceProcs = 0;
1294 int mNewNumAServiceProcs = 0;
1295 int mNewNumServiceProcs = 0;
1298 * Allow the current computed overall memory level of the system to go down?
1299 * This is set to false when we are killing processes for reasons other than
1300 * memory management, so that the now smaller process list will not be taken as
1301 * an indication that memory is tighter.
1303 boolean mAllowLowerMemLevel = false;
1306 * The last computed memory level, for holding when we are in a state that
1307 * processes are going away for other reasons.
1309 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1312 * The last total number of process we have, to determine if changes actually look
1313 * like a shrinking number of process due to lower RAM.
1315 int mLastNumProcesses;
1318 * The uptime of the last time we performed idle maintenance.
1320 long mLastIdleTime = SystemClock.uptimeMillis();
1323 * Total time spent with RAM that has been added in the past since the last idle time.
1325 long mLowRamTimeSinceLastIdle = 0;
1328 * If RAM is currently low, when that horrible situation started.
1330 long mLowRamStartTime = 0;
1333 * For reporting to battery stats the current top application.
1335 private String mCurResumedPackage = null;
1336 private int mCurResumedUid = -1;
1339 * For reporting to battery stats the apps currently running foreground
1340 * service. The ProcessMap is package/uid tuples; each of these contain
1341 * an array of the currently foreground processes.
1343 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1344 = new ProcessMap<ArrayList<ProcessRecord>>();
1347 * This is set if we had to do a delayed dexopt of an app before launching
1348 * it, to increase the ANR timeouts in that case.
1353 * Set if the systemServer made a call to enterSafeMode.
1358 * If true, we are running under a test environment so will sample PSS from processes
1359 * much more rapidly to try to collect better data when the tests are rapidly
1360 * running through apps.
1362 boolean mTestPssMode = false;
1364 String mDebugApp = null;
1365 boolean mWaitForDebugger = false;
1366 boolean mDebugTransient = false;
1367 String mOrigDebugApp = null;
1368 boolean mOrigWaitForDebugger = false;
1369 boolean mAlwaysFinishActivities = false;
1370 boolean mLenientBackgroundCheck = false;
1371 boolean mForceResizableActivities;
1372 boolean mSupportsMultiWindow;
1373 boolean mSupportsFreeformWindowManagement;
1374 boolean mSupportsPictureInPicture;
1375 boolean mSupportsLeanbackOnly;
1376 Rect mDefaultPinnedStackBounds;
1377 IActivityController mController = null;
1378 boolean mControllerIsAMonkey = false;
1379 String mProfileApp = null;
1380 ProcessRecord mProfileProc = null;
1381 String mProfileFile;
1382 ParcelFileDescriptor mProfileFd;
1383 int mSamplingInterval = 0;
1384 boolean mAutoStopProfiler = false;
1385 int mProfileType = 0;
1386 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1387 String mMemWatchDumpProcName;
1388 String mMemWatchDumpFile;
1389 int mMemWatchDumpPid;
1390 int mMemWatchDumpUid;
1391 String mTrackAllocationApp = null;
1392 String mNativeDebuggingApp = null;
1394 final long[] mTmpLong = new long[2];
1396 static final class ProcessChangeItem {
1397 static final int CHANGE_ACTIVITIES = 1<<0;
1398 static final int CHANGE_PROCESS_STATE = 1<<1;
1403 boolean foregroundActivities;
1406 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1407 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1409 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1410 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1412 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1413 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1415 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1416 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1419 * Runtime CPU use collection thread. This object's lock is used to
1420 * perform synchronization with the thread (notifying it to run).
1422 final Thread mProcessCpuThread;
1425 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1426 * Must acquire this object's lock when accessing it.
1427 * NOTE: this lock will be held while doing long operations (trawling
1428 * through all processes in /proc), so it should never be acquired by
1429 * any critical paths such as when holding the main activity manager lock.
1431 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1432 MONITOR_THREAD_CPU_USAGE);
1433 final AtomicLong mLastCpuTime = new AtomicLong(0);
1434 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1436 long mLastWriteTime = 0;
1439 * Used to retain an update lock when the foreground activity is in
1442 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1445 * Set to true after the system has finished booting.
1447 boolean mBooted = false;
1449 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1450 int mProcessLimitOverride = -1;
1452 WindowManagerService mWindowManager;
1453 final ActivityThread mSystemThread;
1455 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1456 final ProcessRecord mApp;
1458 final IApplicationThread mAppThread;
1460 AppDeathRecipient(ProcessRecord app, int pid,
1461 IApplicationThread thread) {
1462 if (DEBUG_ALL) Slog.v(
1463 TAG, "New death recipient " + this
1464 + " for thread " + thread.asBinder());
1467 mAppThread = thread;
1471 public void binderDied() {
1472 if (DEBUG_ALL) Slog.v(
1473 TAG, "Death received in " + this
1474 + " for thread " + mAppThread.asBinder());
1475 synchronized(ActivityManagerService.this) {
1476 appDiedLocked(mApp, mPid, mAppThread, true);
1481 static final int SHOW_ERROR_UI_MSG = 1;
1482 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1483 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1484 static final int UPDATE_CONFIGURATION_MSG = 4;
1485 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1486 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1487 static final int SERVICE_TIMEOUT_MSG = 12;
1488 static final int UPDATE_TIME_ZONE = 13;
1489 static final int SHOW_UID_ERROR_UI_MSG = 14;
1490 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1491 static final int PROC_START_TIMEOUT_MSG = 20;
1492 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1493 static final int KILL_APPLICATION_MSG = 22;
1494 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1495 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1496 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1497 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1498 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1499 static final int CLEAR_DNS_CACHE_MSG = 28;
1500 static final int UPDATE_HTTP_PROXY_MSG = 29;
1501 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1502 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1503 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1504 static final int REPORT_MEM_USAGE_MSG = 33;
1505 static final int REPORT_USER_SWITCH_MSG = 34;
1506 static final int CONTINUE_USER_SWITCH_MSG = 35;
1507 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1508 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1509 static final int PERSIST_URI_GRANTS_MSG = 38;
1510 static final int REQUEST_ALL_PSS_MSG = 39;
1511 static final int START_PROFILES_MSG = 40;
1512 static final int UPDATE_TIME = 41;
1513 static final int SYSTEM_USER_START_MSG = 42;
1514 static final int SYSTEM_USER_CURRENT_MSG = 43;
1515 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1516 static final int FINISH_BOOTING_MSG = 45;
1517 static final int START_USER_SWITCH_UI_MSG = 46;
1518 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1519 static final int DISMISS_DIALOG_UI_MSG = 48;
1520 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1521 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1522 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1523 static final int DELETE_DUMPHEAP_MSG = 52;
1524 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1525 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1526 static final int REPORT_TIME_TRACKER_MSG = 55;
1527 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1528 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1529 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1530 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1531 static final int IDLE_UIDS_MSG = 60;
1532 static final int SYSTEM_USER_UNLOCK_MSG = 61;
1533 static final int LOG_STACK_STATE = 62;
1534 static final int VR_MODE_CHANGE_MSG = 63;
1535 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1536 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1537 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1538 static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1539 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1540 static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1541 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1543 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1544 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1545 static final int FIRST_COMPAT_MODE_MSG = 300;
1546 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1548 static ServiceThread sKillThread = null;
1549 static KillHandler sKillHandler = null;
1551 CompatModeDialog mCompatModeDialog;
1552 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1553 long mLastMemUsageReportTime = 0;
1556 * Flag whether the current user is a "monkey", i.e. whether
1557 * the UI is driven by a UI automation tool.
1559 private boolean mUserIsMonkey;
1561 /** Flag whether the device has a Recents UI */
1562 boolean mHasRecents;
1564 /** The dimensions of the thumbnails in the Recents UI. */
1565 int mThumbnailWidth;
1566 int mThumbnailHeight;
1567 float mFullscreenThumbnailScale;
1569 final ServiceThread mHandlerThread;
1570 final MainHandler mHandler;
1571 final UiHandler mUiHandler;
1573 PackageManagerInternal mPackageManagerInt;
1575 // VoiceInteraction session ID that changes for each new request except when
1576 // being called for multiwindow assist in a single session.
1577 private int mViSessionId = 1000;
1579 final boolean mPermissionReviewRequired;
1581 final class KillHandler extends Handler {
1582 static final int KILL_PROCESS_GROUP_MSG = 4000;
1584 public KillHandler(Looper looper) {
1585 super(looper, null, true);
1589 public void handleMessage(Message msg) {
1591 case KILL_PROCESS_GROUP_MSG:
1593 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1594 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1595 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1600 super.handleMessage(msg);
1605 final class UiHandler extends Handler {
1606 public UiHandler() {
1607 super(com.android.server.UiThread.get().getLooper(), null, true);
1611 public void handleMessage(Message msg) {
1613 case SHOW_ERROR_UI_MSG: {
1614 mAppErrors.handleShowAppErrorUi(msg);
1615 ensureBootCompleted();
1617 case SHOW_NOT_RESPONDING_UI_MSG: {
1618 mAppErrors.handleShowAnrUi(msg);
1619 ensureBootCompleted();
1621 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1622 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1623 synchronized (ActivityManagerService.this) {
1624 ProcessRecord proc = (ProcessRecord) data.get("app");
1626 Slog.e(TAG, "App not found when showing strict mode dialog.");
1629 if (proc.crashDialog != null) {
1630 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1633 AppErrorResult res = (AppErrorResult) data.get("result");
1634 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1635 Dialog d = new StrictModeViolationDialog(mContext,
1636 ActivityManagerService.this, res, proc);
1638 proc.crashDialog = d;
1640 // The device is asleep, so just pretend that the user
1641 // saw a crash dialog and hit "force quit".
1645 ensureBootCompleted();
1647 case SHOW_FACTORY_ERROR_UI_MSG: {
1648 Dialog d = new FactoryErrorDialog(
1649 mContext, msg.getData().getCharSequence("msg"));
1651 ensureBootCompleted();
1653 case WAIT_FOR_DEBUGGER_UI_MSG: {
1654 synchronized (ActivityManagerService.this) {
1655 ProcessRecord app = (ProcessRecord)msg.obj;
1656 if (msg.arg1 != 0) {
1657 if (!app.waitedForDebugger) {
1658 Dialog d = new AppWaitingForDebuggerDialog(
1659 ActivityManagerService.this,
1662 app.waitedForDebugger = true;
1666 if (app.waitDialog != null) {
1667 app.waitDialog.dismiss();
1668 app.waitDialog = null;
1673 case SHOW_UID_ERROR_UI_MSG: {
1675 AlertDialog d = new BaseErrorDialog(mContext);
1676 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1677 d.setCancelable(false);
1678 d.setTitle(mContext.getText(R.string.android_system_label));
1679 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1680 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1681 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1685 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1687 AlertDialog d = new BaseErrorDialog(mContext);
1688 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1689 d.setCancelable(false);
1690 d.setTitle(mContext.getText(R.string.android_system_label));
1691 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1692 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1693 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1697 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1698 synchronized (ActivityManagerService.this) {
1699 ActivityRecord ar = (ActivityRecord) msg.obj;
1700 if (mCompatModeDialog != null) {
1701 if (mCompatModeDialog.mAppInfo.packageName.equals(
1702 ar.info.applicationInfo.packageName)) {
1705 mCompatModeDialog.dismiss();
1706 mCompatModeDialog = null;
1708 if (ar != null && false) {
1709 if (mCompatModePackages.getPackageAskCompatModeLocked(
1711 int mode = mCompatModePackages.computeCompatModeLocked(
1712 ar.info.applicationInfo);
1713 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1714 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1715 mCompatModeDialog = new CompatModeDialog(
1716 ActivityManagerService.this, mContext,
1717 ar.info.applicationInfo);
1718 mCompatModeDialog.show();
1725 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1726 synchronized (ActivityManagerService.this) {
1727 final ActivityRecord ar = (ActivityRecord) msg.obj;
1728 if (mUnsupportedDisplaySizeDialog != null) {
1729 mUnsupportedDisplaySizeDialog.dismiss();
1730 mUnsupportedDisplaySizeDialog = null;
1732 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1734 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1735 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1736 mUnsupportedDisplaySizeDialog.show();
1741 case START_USER_SWITCH_UI_MSG: {
1742 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1745 case DISMISS_DIALOG_UI_MSG: {
1746 final Dialog d = (Dialog) msg.obj;
1750 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1751 dispatchProcessesChanged();
1754 case DISPATCH_PROCESS_DIED_UI_MSG: {
1755 final int pid = msg.arg1;
1756 final int uid = msg.arg2;
1757 dispatchProcessDied(pid, uid);
1760 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1761 dispatchUidsChanged();
1767 final class MainHandler extends Handler {
1768 public MainHandler(Looper looper) {
1769 super(looper, null, true);
1773 public void handleMessage(Message msg) {
1775 case UPDATE_CONFIGURATION_MSG: {
1776 final ContentResolver resolver = mContext.getContentResolver();
1777 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1780 case GC_BACKGROUND_PROCESSES_MSG: {
1781 synchronized (ActivityManagerService.this) {
1782 performAppGcsIfAppropriateLocked();
1785 case SERVICE_TIMEOUT_MSG: {
1788 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1790 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1793 mServices.serviceTimeout((ProcessRecord)msg.obj);
1795 case UPDATE_TIME_ZONE: {
1796 synchronized (ActivityManagerService.this) {
1797 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1798 ProcessRecord r = mLruProcesses.get(i);
1799 if (r.thread != null) {
1801 r.thread.updateTimeZone();
1802 } catch (RemoteException ex) {
1803 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1809 case CLEAR_DNS_CACHE_MSG: {
1810 synchronized (ActivityManagerService.this) {
1811 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1812 ProcessRecord r = mLruProcesses.get(i);
1813 if (r.thread != null) {
1815 r.thread.clearDnsCache();
1816 } catch (RemoteException ex) {
1817 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1823 case UPDATE_HTTP_PROXY_MSG: {
1824 ProxyInfo proxy = (ProxyInfo)msg.obj;
1827 String exclList = "";
1828 Uri pacFileUrl = Uri.EMPTY;
1829 if (proxy != null) {
1830 host = proxy.getHost();
1831 port = Integer.toString(proxy.getPort());
1832 exclList = proxy.getExclusionListAsString();
1833 pacFileUrl = proxy.getPacFileUrl();
1835 synchronized (ActivityManagerService.this) {
1836 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1837 ProcessRecord r = mLruProcesses.get(i);
1838 if (r.thread != null) {
1840 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1841 } catch (RemoteException ex) {
1842 Slog.w(TAG, "Failed to update http proxy for: " +
1843 r.info.processName);
1849 case PROC_START_TIMEOUT_MSG: {
1852 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1854 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1857 ProcessRecord app = (ProcessRecord)msg.obj;
1858 synchronized (ActivityManagerService.this) {
1859 processStartTimedOutLocked(app);
1862 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1863 ProcessRecord app = (ProcessRecord)msg.obj;
1864 synchronized (ActivityManagerService.this) {
1865 processContentProviderPublishTimedOutLocked(app);
1868 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1869 synchronized (ActivityManagerService.this) {
1870 mActivityStarter.doPendingActivityLaunchesLocked(true);
1873 case KILL_APPLICATION_MSG: {
1874 synchronized (ActivityManagerService.this) {
1875 final int appId = msg.arg1;
1876 final int userId = msg.arg2;
1877 Bundle bundle = (Bundle)msg.obj;
1878 String pkg = bundle.getString("pkg");
1879 String reason = bundle.getString("reason");
1880 forceStopPackageLocked(pkg, appId, false, false, true, false,
1881 false, userId, reason);
1884 case FINALIZE_PENDING_INTENT_MSG: {
1885 ((PendingIntentRecord)msg.obj).completeFinalize();
1887 case POST_HEAVY_NOTIFICATION_MSG: {
1888 INotificationManager inm = NotificationManager.getService();
1893 ActivityRecord root = (ActivityRecord)msg.obj;
1894 ProcessRecord process = root.app;
1895 if (process == null) {
1900 Context context = mContext.createPackageContext(process.info.packageName, 0);
1901 String text = mContext.getString(R.string.heavy_weight_notification,
1902 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1903 Notification notification = new Notification.Builder(context)
1904 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1908 .setColor(mContext.getColor(
1909 com.android.internal.R.color.system_notification_accent_color))
1910 .setContentTitle(text)
1912 mContext.getText(R.string.heavy_weight_notification_detail))
1913 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1914 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1915 new UserHandle(root.userId)))
1918 int[] outId = new int[1];
1919 inm.enqueueNotificationWithTag("android", "android", null,
1920 R.string.heavy_weight_notification,
1921 notification, outId, root.userId);
1922 } catch (RuntimeException e) {
1923 Slog.w(ActivityManagerService.TAG,
1924 "Error showing notification for heavy-weight app", e);
1925 } catch (RemoteException e) {
1927 } catch (NameNotFoundException e) {
1928 Slog.w(TAG, "Unable to create context for heavy notification", e);
1931 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1932 INotificationManager inm = NotificationManager.getService();
1937 inm.cancelNotificationWithTag("android", null,
1938 R.string.heavy_weight_notification, msg.arg1);
1939 } catch (RuntimeException e) {
1940 Slog.w(ActivityManagerService.TAG,
1941 "Error canceling notification for service", e);
1942 } catch (RemoteException e) {
1945 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1946 synchronized (ActivityManagerService.this) {
1947 checkExcessivePowerUsageLocked(true);
1948 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1949 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1950 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1953 case REPORT_MEM_USAGE_MSG: {
1954 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1955 Thread thread = new Thread() {
1956 @Override public void run() {
1957 reportMemUsage(memInfos);
1963 case REPORT_USER_SWITCH_MSG: {
1964 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1967 case CONTINUE_USER_SWITCH_MSG: {
1968 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1971 case USER_SWITCH_TIMEOUT_MSG: {
1972 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1975 case IMMERSIVE_MODE_LOCK_MSG: {
1976 final boolean nextState = (msg.arg1 != 0);
1977 if (mUpdateLock.isHeld() != nextState) {
1978 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1979 "Applying new update lock state '" + nextState
1980 + "' for " + (ActivityRecord)msg.obj);
1982 mUpdateLock.acquire();
1984 mUpdateLock.release();
1989 case PERSIST_URI_GRANTS_MSG: {
1990 writeGrantedUriPermissions();
1993 case REQUEST_ALL_PSS_MSG: {
1994 synchronized (ActivityManagerService.this) {
1995 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1999 case START_PROFILES_MSG: {
2000 synchronized (ActivityManagerService.this) {
2001 mUserController.startProfilesLocked();
2006 synchronized (ActivityManagerService.this) {
2007 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2008 ProcessRecord r = mLruProcesses.get(i);
2009 if (r.thread != null) {
2011 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2012 } catch (RemoteException ex) {
2013 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2020 case SYSTEM_USER_START_MSG: {
2021 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2022 Integer.toString(msg.arg1), msg.arg1);
2023 mSystemServiceManager.startUser(msg.arg1);
2026 case SYSTEM_USER_UNLOCK_MSG: {
2027 final int userId = msg.arg1;
2028 mSystemServiceManager.unlockUser(userId);
2029 synchronized (ActivityManagerService.this) {
2030 mRecentTasks.loadUserRecentsLocked(userId);
2032 if (userId == UserHandle.USER_SYSTEM) {
2033 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2035 installEncryptionUnawareProviders(userId);
2036 mUserController.finishUserUnlocked((UserState) msg.obj);
2039 case SYSTEM_USER_CURRENT_MSG: {
2040 mBatteryStatsService.noteEvent(
2041 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2042 Integer.toString(msg.arg2), msg.arg2);
2043 mBatteryStatsService.noteEvent(
2044 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2045 Integer.toString(msg.arg1), msg.arg1);
2046 mSystemServiceManager.switchUser(msg.arg1);
2049 case ENTER_ANIMATION_COMPLETE_MSG: {
2050 synchronized (ActivityManagerService.this) {
2051 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2052 if (r != null && r.app != null && r.app.thread != null) {
2054 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2055 } catch (RemoteException e) {
2061 case FINISH_BOOTING_MSG: {
2062 if (msg.arg1 != 0) {
2063 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2065 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2067 if (msg.arg2 != 0) {
2068 enableScreenAfterBoot();
2072 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2074 Locale l = (Locale) msg.obj;
2075 IBinder service = ServiceManager.getService("mount");
2076 IMountService mountService = IMountService.Stub.asInterface(service);
2077 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2078 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2079 } catch (RemoteException e) {
2080 Log.e(TAG, "Error storing locale for decryption UI", e);
2084 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2085 synchronized (ActivityManagerService.this) {
2086 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2088 // Make a one-way callback to the listener
2089 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2090 } catch (RemoteException e){
2091 // Handled by the RemoteCallbackList
2094 mTaskStackListeners.finishBroadcast();
2098 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2099 synchronized (ActivityManagerService.this) {
2100 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2102 // Make a one-way callback to the listener
2103 mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2104 } catch (RemoteException e){
2105 // Handled by the RemoteCallbackList
2108 mTaskStackListeners.finishBroadcast();
2112 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2113 synchronized (ActivityManagerService.this) {
2114 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2116 // Make a one-way callback to the listener
2117 mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2118 } catch (RemoteException e){
2119 // Handled by the RemoteCallbackList
2122 mTaskStackListeners.finishBroadcast();
2126 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2127 synchronized (ActivityManagerService.this) {
2128 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2130 // Make a one-way callback to the listener
2131 mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2132 } catch (RemoteException e){
2133 // Handled by the RemoteCallbackList
2136 mTaskStackListeners.finishBroadcast();
2140 case NOTIFY_FORCED_RESIZABLE_MSG: {
2141 synchronized (ActivityManagerService.this) {
2142 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2144 // Make a one-way callback to the listener
2145 mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2146 (String) msg.obj, msg.arg1);
2147 } catch (RemoteException e){
2148 // Handled by the RemoteCallbackList
2151 mTaskStackListeners.finishBroadcast();
2155 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2156 synchronized (ActivityManagerService.this) {
2157 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2159 // Make a one-way callback to the listener
2160 mTaskStackListeners.getBroadcastItem(i)
2161 .onActivityDismissingDockedStack();
2162 } catch (RemoteException e){
2163 // Handled by the RemoteCallbackList
2166 mTaskStackListeners.finishBroadcast();
2170 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2171 final int uid = msg.arg1;
2172 final byte[] firstPacket = (byte[]) msg.obj;
2174 synchronized (mPidsSelfLocked) {
2175 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2176 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2179 p.thread.notifyCleartextNetwork(firstPacket);
2180 } catch (RemoteException ignored) {
2187 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2188 final String procName;
2190 final long memLimit;
2191 final String reportPackage;
2192 synchronized (ActivityManagerService.this) {
2193 procName = mMemWatchDumpProcName;
2194 uid = mMemWatchDumpUid;
2195 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2197 val = mMemWatchProcesses.get(procName, 0);
2200 memLimit = val.first;
2201 reportPackage = val.second;
2204 reportPackage = null;
2207 if (procName == null) {
2211 if (DEBUG_PSS) Slog.d(TAG_PSS,
2212 "Showing dump heap notification from " + procName + "/" + uid);
2214 INotificationManager inm = NotificationManager.getService();
2219 String text = mContext.getString(R.string.dump_heap_notification, procName);
2222 Intent deleteIntent = new Intent();
2223 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2224 Intent intent = new Intent();
2225 intent.setClassName("android", DumpHeapActivity.class.getName());
2226 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2227 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2228 if (reportPackage != null) {
2229 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2231 int userId = UserHandle.getUserId(uid);
2232 Notification notification = new Notification.Builder(mContext)
2233 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2236 .setAutoCancel(true)
2238 .setColor(mContext.getColor(
2239 com.android.internal.R.color.system_notification_accent_color))
2240 .setContentTitle(text)
2242 mContext.getText(R.string.dump_heap_notification_detail))
2243 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2244 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2245 new UserHandle(userId)))
2246 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2247 deleteIntent, 0, UserHandle.SYSTEM))
2251 int[] outId = new int[1];
2252 inm.enqueueNotificationWithTag("android", "android", null,
2253 R.string.dump_heap_notification,
2254 notification, outId, userId);
2255 } catch (RuntimeException e) {
2256 Slog.w(ActivityManagerService.TAG,
2257 "Error showing notification for dump heap", e);
2258 } catch (RemoteException e) {
2261 case DELETE_DUMPHEAP_MSG: {
2262 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2263 DumpHeapActivity.JAVA_URI,
2264 Intent.FLAG_GRANT_READ_URI_PERMISSION
2265 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2266 UserHandle.myUserId());
2267 synchronized (ActivityManagerService.this) {
2268 mMemWatchDumpFile = null;
2269 mMemWatchDumpProcName = null;
2270 mMemWatchDumpPid = -1;
2271 mMemWatchDumpUid = -1;
2274 case FOREGROUND_PROFILE_CHANGED_MSG: {
2275 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2277 case REPORT_TIME_TRACKER_MSG: {
2278 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2279 tracker.deliverResult(mContext);
2281 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2282 mUserController.dispatchUserSwitchComplete(msg.arg1);
2284 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2285 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2287 connection.shutdown();
2288 } catch (RemoteException e) {
2289 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2291 // Only a UiAutomation can set this flag and now that
2292 // it is finished we make sure it is reset to its default.
2293 mUserIsMonkey = false;
2295 case APP_BOOST_DEACTIVATE_MSG: {
2296 synchronized(ActivityManagerService.this) {
2298 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2299 nativeMigrateFromBoost();
2301 mBoostStartTime = 0;
2303 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2304 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2309 case IDLE_UIDS_MSG: {
2312 case LOG_STACK_STATE: {
2313 synchronized (ActivityManagerService.this) {
2314 mStackSupervisor.logStackState();
2317 case VR_MODE_CHANGE_MSG: {
2318 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2319 if (vrService == null) {
2322 final ActivityRecord r = (ActivityRecord) msg.obj;
2324 ComponentName requestedPackage;
2325 ComponentName callingPackage;
2327 synchronized (ActivityManagerService.this) {
2328 vrMode = r.requestedVrComponent != null;
2329 requestedPackage = r.requestedVrComponent;
2331 callingPackage = r.info.getComponentName();
2332 if (mInVrMode != vrMode) {
2334 mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2335 if (r.app != null) {
2336 ProcessRecord proc = r.app;
2337 if (proc.vrThreadTid > 0) {
2338 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2340 if (mInVrMode == true) {
2341 Process.setThreadScheduler(proc.vrThreadTid,
2342 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2344 Process.setThreadScheduler(proc.vrThreadTid,
2345 Process.SCHED_OTHER, 0);
2347 } catch (IllegalArgumentException e) {
2348 Slog.w(TAG, "Failed to set scheduling policy, thread does"
2349 + " not exist:\n" + e);
2356 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2358 case VR_MODE_APPLY_IF_NEEDED_MSG: {
2359 final ActivityRecord r = (ActivityRecord) msg.obj;
2360 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2362 applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2363 r.info.getComponentName(), false);
2370 static final int COLLECT_PSS_BG_MSG = 1;
2372 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2374 public void handleMessage(Message msg) {
2376 case COLLECT_PSS_BG_MSG: {
2377 long start = SystemClock.uptimeMillis();
2378 MemInfoReader memInfo = null;
2379 synchronized (ActivityManagerService.this) {
2380 if (mFullPssPending) {
2381 mFullPssPending = false;
2382 memInfo = new MemInfoReader();
2385 if (memInfo != null) {
2386 updateCpuStatsNow();
2387 long nativeTotalPss = 0;
2388 final List<ProcessCpuTracker.Stats> stats;
2389 synchronized (mProcessCpuTracker) {
2390 stats = mProcessCpuTracker.getStats( (st)-> {
2391 return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2394 final int N = stats.size();
2395 for (int j = 0; j < N; j++) {
2396 synchronized (mPidsSelfLocked) {
2397 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2398 // This is one of our own processes; skip it.
2402 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2404 memInfo.readMemInfo();
2405 synchronized (ActivityManagerService.this) {
2406 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2407 + (SystemClock.uptimeMillis()-start) + "ms");
2408 final long cachedKb = memInfo.getCachedSizeKb();
2409 final long freeKb = memInfo.getFreeSizeKb();
2410 final long zramKb = memInfo.getZramTotalSizeKb();
2411 final long kernelKb = memInfo.getKernelUsedSizeKb();
2412 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2413 kernelKb*1024, nativeTotalPss*1024);
2414 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2420 long[] tmp = new long[2];
2426 synchronized (ActivityManagerService.this) {
2427 if (mPendingPssProcesses.size() <= 0) {
2428 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2429 "Collected PSS of " + num + " processes in "
2430 + (SystemClock.uptimeMillis() - start) + "ms");
2431 mPendingPssProcesses.clear();
2434 proc = mPendingPssProcesses.remove(0);
2435 procState = proc.pssProcState;
2436 lastPssTime = proc.lastPssTime;
2437 if (proc.thread != null && procState == proc.setProcState
2438 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2439 < SystemClock.uptimeMillis()) {
2447 long pss = Debug.getPss(pid, tmp, null);
2448 synchronized (ActivityManagerService.this) {
2449 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2450 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2452 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2453 SystemClock.uptimeMillis());
2463 public void setSystemProcess() {
2465 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2466 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2467 ServiceManager.addService("meminfo", new MemBinder(this));
2468 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2469 ServiceManager.addService("dbinfo", new DbBinder(this));
2470 if (MONITOR_CPU_USAGE) {
2471 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2473 ServiceManager.addService("permission", new PermissionController(this));
2474 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2476 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2477 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2478 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2480 synchronized (this) {
2481 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2482 app.persistent = true;
2484 app.maxAdj = ProcessList.SYSTEM_ADJ;
2485 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2486 synchronized (mPidsSelfLocked) {
2487 mPidsSelfLocked.put(app.pid, app);
2489 updateLruProcessLocked(app, false, null);
2490 updateOomAdjLocked();
2492 } catch (PackageManager.NameNotFoundException e) {
2493 throw new RuntimeException(
2494 "Unable to find android system package", e);
2498 public void setWindowManager(WindowManagerService wm) {
2499 mWindowManager = wm;
2500 mStackSupervisor.setWindowManager(wm);
2501 mActivityStarter.setWindowManager(wm);
2504 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2505 mUsageStatsService = usageStatsManager;
2508 public void startObservingNativeCrashes() {
2509 final NativeCrashListener ncl = new NativeCrashListener(this);
2513 public IAppOpsService getAppOpsService() {
2514 return mAppOpsService;
2517 static class MemBinder extends Binder {
2518 ActivityManagerService mActivityManagerService;
2519 MemBinder(ActivityManagerService activityManagerService) {
2520 mActivityManagerService = activityManagerService;
2524 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2525 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2526 != PackageManager.PERMISSION_GRANTED) {
2527 pw.println("Permission Denial: can't dump meminfo from from pid="
2528 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2529 + " without permission " + android.Manifest.permission.DUMP);
2533 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2537 static class GraphicsBinder extends Binder {
2538 ActivityManagerService mActivityManagerService;
2539 GraphicsBinder(ActivityManagerService activityManagerService) {
2540 mActivityManagerService = activityManagerService;
2544 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2545 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2546 != PackageManager.PERMISSION_GRANTED) {
2547 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2548 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2549 + " without permission " + android.Manifest.permission.DUMP);
2553 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2557 static class DbBinder extends Binder {
2558 ActivityManagerService mActivityManagerService;
2559 DbBinder(ActivityManagerService activityManagerService) {
2560 mActivityManagerService = activityManagerService;
2564 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2565 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2566 != PackageManager.PERMISSION_GRANTED) {
2567 pw.println("Permission Denial: can't dump dbinfo from from pid="
2568 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2569 + " without permission " + android.Manifest.permission.DUMP);
2573 mActivityManagerService.dumpDbInfo(fd, pw, args);
2577 static class CpuBinder extends Binder {
2578 ActivityManagerService mActivityManagerService;
2579 CpuBinder(ActivityManagerService activityManagerService) {
2580 mActivityManagerService = activityManagerService;
2584 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2585 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2586 != PackageManager.PERMISSION_GRANTED) {
2587 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2588 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2589 + " without permission " + android.Manifest.permission.DUMP);
2593 synchronized (mActivityManagerService.mProcessCpuTracker) {
2594 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2595 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2596 SystemClock.uptimeMillis()));
2601 public static final class Lifecycle extends SystemService {
2602 private final ActivityManagerService mService;
2604 public Lifecycle(Context context) {
2606 mService = new ActivityManagerService(context);
2610 public void onStart() {
2614 public ActivityManagerService getService() {
2619 // Note: This method is invoked on the main thread but may need to attach various
2620 // handlers to other threads. So take care to be explicit about the looper.
2621 public ActivityManagerService(Context systemContext) {
2622 mContext = systemContext;
2623 mFactoryTest = FactoryTest.getMode();
2624 mSystemThread = ActivityThread.currentActivityThread();
2626 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2628 mPermissionReviewRequired = mContext.getResources().getBoolean(
2629 com.android.internal.R.bool.config_permissionReviewRequired);
2631 mHandlerThread = new ServiceThread(TAG,
2632 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2633 mHandlerThread.start();
2634 mHandler = new MainHandler(mHandlerThread.getLooper());
2635 mUiHandler = new UiHandler();
2637 /* static; one-time init here */
2638 if (sKillHandler == null) {
2639 sKillThread = new ServiceThread(TAG + ":kill",
2640 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2641 sKillThread.start();
2642 sKillHandler = new KillHandler(sKillThread.getLooper());
2645 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2646 "foreground", BROADCAST_FG_TIMEOUT, false);
2647 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2648 "background", BROADCAST_BG_TIMEOUT, true);
2649 mBroadcastQueues[0] = mFgBroadcastQueue;
2650 mBroadcastQueues[1] = mBgBroadcastQueue;
2652 mServices = new ActiveServices(this);
2653 mProviderMap = new ProviderMap(this);
2654 mAppErrors = new AppErrors(mContext, this);
2656 // TODO: Move creation of battery stats service outside of activity manager service.
2657 File dataDir = Environment.getDataDirectory();
2658 File systemDir = new File(dataDir, "system");
2660 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2661 mBatteryStatsService.getActiveStatistics().readLocked();
2662 mBatteryStatsService.scheduleWriteToDisk();
2663 mOnBattery = DEBUG_POWER ? true
2664 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2665 mBatteryStatsService.getActiveStatistics().setCallback(this);
2667 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2669 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2670 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2671 new IAppOpsCallback.Stub() {
2672 @Override public void opChanged(int op, int uid, String packageName) {
2673 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2674 if (mAppOpsService.checkOperation(op, uid, packageName)
2675 != AppOpsManager.MODE_ALLOWED) {
2676 runInBackgroundDisabled(uid);
2682 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2684 mUserController = new UserController(this);
2686 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2687 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2689 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2690 mUseFifoUiScheduling = true;
2693 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2695 mConfiguration.setToDefaults();
2696 mConfiguration.setLocales(LocaleList.getDefault());
2698 mConfigurationSeq = mConfiguration.seq = 1;
2699 mProcessCpuTracker.init();
2701 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2702 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2703 mStackSupervisor = new ActivityStackSupervisor(this);
2704 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2705 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2707 mProcessCpuThread = new Thread("CpuTracker") {
2713 synchronized(this) {
2714 final long now = SystemClock.uptimeMillis();
2715 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2716 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2717 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2718 // + ", write delay=" + nextWriteDelay);
2719 if (nextWriteDelay < nextCpuDelay) {
2720 nextCpuDelay = nextWriteDelay;
2722 if (nextCpuDelay > 0) {
2723 mProcessCpuMutexFree.set(true);
2724 this.wait(nextCpuDelay);
2727 } catch (InterruptedException e) {
2729 updateCpuStatsNow();
2730 } catch (Exception e) {
2731 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2737 Watchdog.getInstance().addMonitor(this);
2738 Watchdog.getInstance().addThread(mHandler);
2741 public void setSystemServiceManager(SystemServiceManager mgr) {
2742 mSystemServiceManager = mgr;
2745 public void setInstaller(Installer installer) {
2746 mInstaller = installer;
2749 private void start() {
2750 Process.removeAllProcessGroups();
2751 mProcessCpuThread.start();
2753 mBatteryStatsService.publish(mContext);
2754 mAppOpsService.publish(mContext);
2755 Slog.d("AppOps", "AppOpsService published");
2756 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2759 void onUserStoppedLocked(int userId) {
2760 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2763 public void initPowerManagement() {
2764 mStackSupervisor.initPowerManagement();
2765 mBatteryStatsService.initPowerManagement();
2766 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2767 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2768 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2769 mVoiceWakeLock.setReferenceCounted(false);
2773 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2774 throws RemoteException {
2775 if (code == SYSPROPS_TRANSACTION) {
2776 // We need to tell all apps about the system property change.
2777 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2778 synchronized(this) {
2779 final int NP = mProcessNames.getMap().size();
2780 for (int ip=0; ip<NP; ip++) {
2781 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2782 final int NA = apps.size();
2783 for (int ia=0; ia<NA; ia++) {
2784 ProcessRecord app = apps.valueAt(ia);
2785 if (app.thread != null) {
2786 procs.add(app.thread.asBinder());
2792 int N = procs.size();
2793 for (int i=0; i<N; i++) {
2794 Parcel data2 = Parcel.obtain();
2796 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2797 } catch (RemoteException e) {
2803 return super.onTransact(code, data, reply, flags);
2804 } catch (RuntimeException e) {
2805 // The activity manager only throws security exceptions, so let's
2807 if (!(e instanceof SecurityException)) {
2808 Slog.wtf(TAG, "Activity Manager Crash", e);
2814 void updateCpuStats() {
2815 final long now = SystemClock.uptimeMillis();
2816 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2819 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2820 synchronized (mProcessCpuThread) {
2821 mProcessCpuThread.notify();
2826 void updateCpuStatsNow() {
2827 synchronized (mProcessCpuTracker) {
2828 mProcessCpuMutexFree.set(false);
2829 final long now = SystemClock.uptimeMillis();
2830 boolean haveNewCpuStats = false;
2832 if (MONITOR_CPU_USAGE &&
2833 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2834 mLastCpuTime.set(now);
2835 mProcessCpuTracker.update();
2836 if (mProcessCpuTracker.hasGoodLastStats()) {
2837 haveNewCpuStats = true;
2838 //Slog.i(TAG, mProcessCpu.printCurrentState());
2839 //Slog.i(TAG, "Total CPU usage: "
2840 // + mProcessCpu.getTotalCpuPercent() + "%");
2842 // Slog the cpu usage if the property is set.
2843 if ("true".equals(SystemProperties.get("events.cpu"))) {
2844 int user = mProcessCpuTracker.getLastUserTime();
2845 int system = mProcessCpuTracker.getLastSystemTime();
2846 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2847 int irq = mProcessCpuTracker.getLastIrqTime();
2848 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2849 int idle = mProcessCpuTracker.getLastIdleTime();
2851 int total = user + system + iowait + irq + softIrq + idle;
2852 if (total == 0) total = 1;
2854 EventLog.writeEvent(EventLogTags.CPU,
2855 ((user+system+iowait+irq+softIrq) * 100) / total,
2856 (user * 100) / total,
2857 (system * 100) / total,
2858 (iowait * 100) / total,
2859 (irq * 100) / total,
2860 (softIrq * 100) / total);
2865 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2866 synchronized(bstats) {
2867 synchronized(mPidsSelfLocked) {
2868 if (haveNewCpuStats) {
2869 if (bstats.startAddingCpuLocked()) {
2872 final int N = mProcessCpuTracker.countStats();
2873 for (int i=0; i<N; i++) {
2874 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2878 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2879 totalUTime += st.rel_utime;
2880 totalSTime += st.rel_stime;
2882 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2883 if (ps == null || !ps.isActive()) {
2884 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2885 pr.info.uid, pr.processName);
2887 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2888 pr.curCpuTime += st.rel_utime + st.rel_stime;
2890 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2891 if (ps == null || !ps.isActive()) {
2892 st.batteryStats = ps = bstats.getProcessStatsLocked(
2893 bstats.mapUid(st.uid), st.name);
2895 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2898 final int userTime = mProcessCpuTracker.getLastUserTime();
2899 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2900 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2901 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2902 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2903 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2904 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2905 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2910 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2911 mLastWriteTime = now;
2912 mBatteryStatsService.scheduleWriteToDisk();
2919 public void batteryNeedsCpuUpdate() {
2920 updateCpuStatsNow();
2924 public void batteryPowerChanged(boolean onBattery) {
2925 // When plugging in, update the CPU stats first before changing
2927 updateCpuStatsNow();
2928 synchronized (this) {
2929 synchronized(mPidsSelfLocked) {
2930 mOnBattery = DEBUG_POWER ? true : onBattery;
2936 public void batterySendBroadcast(Intent intent) {
2937 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2938 AppOpsManager.OP_NONE, null, false, false,
2939 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2943 * Initialize the application bind args. These are passed to each
2944 * process when the bindApplication() IPC is sent to the process. They're
2945 * lazily setup to make sure the services are running when they're asked for.
2947 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2948 // Isolated processes won't get this optimization, so that we don't
2949 // violate the rules about which services they have access to.
2951 if (mIsolatedAppBindArgs == null) {
2952 mIsolatedAppBindArgs = new HashMap<>();
2953 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2955 return mIsolatedAppBindArgs;
2958 if (mAppBindArgs == null) {
2959 mAppBindArgs = new HashMap<>();
2961 // Setup the application init args
2962 mAppBindArgs.put("package", ServiceManager.getService("package"));
2963 mAppBindArgs.put("window", ServiceManager.getService("window"));
2964 mAppBindArgs.put(Context.ALARM_SERVICE,
2965 ServiceManager.getService(Context.ALARM_SERVICE));
2967 return mAppBindArgs;
2970 boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2971 if (r == null || mFocusedActivity == r) {
2975 if (!r.isFocusable()) {
2976 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2980 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2982 final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2983 if (wasDoingSetFocusedActivity) Slog.w(TAG,
2984 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2985 mDoingSetFocusedActivity = true;
2987 final ActivityRecord last = mFocusedActivity;
2988 mFocusedActivity = r;
2989 if (r.task.isApplicationTask()) {
2990 if (mCurAppTimeTracker != r.appTimeTracker) {
2991 // We are switching app tracking. Complete the current one.
2992 if (mCurAppTimeTracker != null) {
2993 mCurAppTimeTracker.stop();
2994 mHandler.obtainMessage(
2995 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2996 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2997 mCurAppTimeTracker = null;
2999 if (r.appTimeTracker != null) {
3000 mCurAppTimeTracker = r.appTimeTracker;
3001 startTimeTrackingFocusedActivityLocked();
3004 startTimeTrackingFocusedActivityLocked();
3007 r.appTimeTracker = null;
3009 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3010 // TODO: Probably not, because we don't want to resume voice on switching
3011 // back to this activity
3012 if (r.task.voiceInteractor != null) {
3013 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3015 finishRunningVoiceLocked();
3016 IVoiceInteractionSession session;
3017 if (last != null && ((session = last.task.voiceSession) != null
3018 || (session = last.voiceSession) != null)) {
3019 // We had been in a voice interaction session, but now focused has
3020 // move to something different. Just finish the session, we can't
3021 // return to it and retain the proper state and synchronization with
3022 // the voice interaction service.
3023 finishVoiceTask(session);
3026 if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3027 mWindowManager.setFocusedApp(r.appToken, true);
3029 applyUpdateLockStateLocked(r);
3030 applyUpdateVrModeLocked(r);
3031 if (mFocusedActivity.userId != mLastFocusedUserId) {
3032 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3033 mHandler.obtainMessage(
3034 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3035 mLastFocusedUserId = mFocusedActivity.userId;
3038 // Log a warning if the focused app is changed during the process. This could
3039 // indicate a problem of the focus setting logic!
3040 if (mFocusedActivity != r) Slog.w(TAG,
3041 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3042 mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3044 EventLogTags.writeAmFocusedActivity(
3045 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3046 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3051 final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3052 if (mFocusedActivity != goingAway) {
3056 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3057 if (focusedStack != null) {
3058 final ActivityRecord top = focusedStack.topActivity();
3059 if (top != null && top.userId != mLastFocusedUserId) {
3060 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3061 mHandler.sendMessage(
3062 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3063 mLastFocusedUserId = top.userId;
3067 // Try to move focus to another activity if possible.
3068 if (setFocusedActivityLocked(
3069 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3073 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3074 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3075 mFocusedActivity = null;
3076 EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3080 public void setFocusedStack(int stackId) {
3081 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3082 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3083 final long callingId = Binder.clearCallingIdentity();
3085 synchronized (this) {
3086 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3087 if (stack == null) {
3090 final ActivityRecord r = stack.topRunningActivityLocked();
3091 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3092 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3096 Binder.restoreCallingIdentity(callingId);
3101 public void setFocusedTask(int taskId) {
3102 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3103 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3104 final long callingId = Binder.clearCallingIdentity();
3106 synchronized (this) {
3107 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3111 if (mUserController.shouldConfirmCredentials(task.userId)) {
3112 mActivityStarter.showConfirmDeviceCredential(task.userId);
3113 if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3114 mStackSupervisor.moveTaskToStackLocked(task.taskId,
3115 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3116 "setFocusedTask", ANIMATE);
3120 final ActivityRecord r = task.topRunningActivityLocked();
3121 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3122 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3126 Binder.restoreCallingIdentity(callingId);
3130 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3132 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3133 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3134 synchronized (this) {
3135 if (listener != null) {
3136 mTaskStackListeners.register(listener);
3142 public void notifyActivityDrawn(IBinder token) {
3143 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3144 synchronized (this) {
3145 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3147 r.task.stack.notifyActivityDrawnLocked(r);
3152 final void applyUpdateLockStateLocked(ActivityRecord r) {
3153 // Modifications to the UpdateLock state are done on our handler, outside
3154 // the activity manager's locks. The new state is determined based on the
3155 // state *now* of the relevant activity record. The object is passed to
3156 // the handler solely for logging detail, not to be consulted/modified.
3157 final boolean nextState = r != null && r.immersive;
3158 mHandler.sendMessage(
3159 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3162 final void applyUpdateVrModeLocked(ActivityRecord r) {
3163 mHandler.sendMessage(
3164 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3167 private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3168 mHandler.sendMessage(
3169 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3172 private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3173 ComponentName callingPackage, boolean immediate) {
3174 VrManagerInternal vrService =
3175 LocalServices.getService(VrManagerInternal.class);
3177 vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3179 vrService.setVrMode(enabled, packageName, userId, callingPackage);
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 if (pid != MY_PID && pid >= 0) {
6459 synchronized (mPidsSelfLocked) {
6460 app = mPidsSelfLocked.get(pid);
6467 Slog.w(TAG, "No pending application record for pid " + pid
6468 + " (IApplicationThread " + thread + "); dropping process");
6469 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6470 if (pid > 0 && pid != MY_PID) {
6471 Process.killProcessQuiet(pid);
6472 //TODO: killProcessGroup(app.info.uid, pid);
6475 thread.scheduleExit();
6476 } catch (Exception e) {
6477 // Ignore exceptions.
6483 // If this application record is still attached to a previous
6484 // process, clean it up now.
6485 if (app.thread != null) {
6486 handleAppDiedLocked(app, true, true);
6489 // Tell the process all about itself.
6491 if (DEBUG_ALL) Slog.v(
6492 TAG, "Binding process pid " + pid + " to record " + app);
6494 final String processName = app.processName;
6496 AppDeathRecipient adr = new AppDeathRecipient(
6498 thread.asBinder().linkToDeath(adr, 0);
6499 app.deathRecipient = adr;
6500 } catch (RemoteException e) {
6501 app.resetPackageList(mProcessStats);
6502 startProcessLocked(app, "link fail", processName);
6506 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6508 app.makeActive(thread, mProcessStats);
6509 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6510 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6511 app.forcingToForeground = null;
6512 updateProcessForegroundLocked(app, false, false);
6513 app.hasShownUi = false;
6514 app.debugging = false;
6516 app.killedByAm = false;
6518 // We carefully use the same state that PackageManager uses for
6519 // filtering, since we use this flag to decide if we need to install
6520 // providers when user is unlocked later
6521 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6523 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6525 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6526 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6528 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6529 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6531 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6535 Slog.i(TAG, "Launching preboot mode app: " + app);
6538 if (DEBUG_ALL) Slog.v(
6539 TAG, "New app record " + app
6540 + " thread=" + thread.asBinder() + " pid=" + pid);
6542 int testMode = IApplicationThread.DEBUG_OFF;
6543 if (mDebugApp != null && mDebugApp.equals(processName)) {
6544 testMode = mWaitForDebugger
6545 ? IApplicationThread.DEBUG_WAIT
6546 : IApplicationThread.DEBUG_ON;
6547 app.debugging = true;
6548 if (mDebugTransient) {
6549 mDebugApp = mOrigDebugApp;
6550 mWaitForDebugger = mOrigWaitForDebugger;
6553 String profileFile = app.instrumentationProfileFile;
6554 ParcelFileDescriptor profileFd = null;
6555 int samplingInterval = 0;
6556 boolean profileAutoStop = false;
6557 if (mProfileApp != null && mProfileApp.equals(processName)) {
6559 profileFile = mProfileFile;
6560 profileFd = mProfileFd;
6561 samplingInterval = mSamplingInterval;
6562 profileAutoStop = mAutoStopProfiler;
6564 boolean enableTrackAllocation = false;
6565 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6566 enableTrackAllocation = true;
6567 mTrackAllocationApp = null;
6570 // If the app is being launched for restore or full backup, set it up specially
6571 boolean isRestrictedBackupMode = false;
6572 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6573 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6574 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6575 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6576 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6579 if (app.instrumentationClass != null) {
6580 notifyPackageUse(app.instrumentationClass.getPackageName(),
6581 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6583 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6584 + processName + " with config " + mConfiguration);
6585 ApplicationInfo appInfo = app.instrumentationInfo != null
6586 ? app.instrumentationInfo : app.info;
6587 app.compat = compatibilityInfoForPackageLocked(appInfo);
6588 if (profileFd != null) {
6589 profileFd = profileFd.dup();
6591 ProfilerInfo profilerInfo = profileFile == null ? null
6592 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6593 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6594 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6595 app.instrumentationUiAutomationConnection, testMode,
6596 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6597 isRestrictedBackupMode || !normalMode, app.persistent,
6598 new Configuration(mConfiguration), app.compat,
6599 getCommonServicesLocked(app.isolated),
6600 mCoreSettingsObserver.getCoreSettingsLocked());
6601 updateLruProcessLocked(app, false, null);
6602 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6603 } catch (Exception e) {
6604 // todo: Yikes! What should we do? For now we will try to
6605 // start another process, but that could easily get us in
6606 // an infinite loop of restarting processes...
6607 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6609 app.resetPackageList(mProcessStats);
6610 app.unlinkDeathRecipient();
6611 startProcessLocked(app, "bind fail", processName);
6615 // Remove this record from the list of starting applications.
6616 mPersistentStartingProcesses.remove(app);
6617 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6618 "Attach application locked removing on hold: " + app);
6619 mProcessesOnHold.remove(app);
6621 boolean badApp = false;
6622 boolean didSomething = false;
6624 // See if the top visible activity is waiting to run in this process...
6627 if (mStackSupervisor.attachApplicationLocked(app)) {
6628 didSomething = true;
6630 } catch (Exception e) {
6631 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6636 // Find any services that should be running in this process...
6639 didSomething |= mServices.attachApplicationLocked(app, processName);
6640 } catch (Exception e) {
6641 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6646 // Check if a next-broadcast receiver is in this process...
6647 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6649 didSomething |= sendPendingBroadcastsLocked(app);
6650 } catch (Exception e) {
6651 // If the app died trying to launch the receiver we declare it 'bad'
6652 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6657 // Check whether the next backup agent is in this process...
6658 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6659 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6660 "New app is backup target, launching agent for " + app);
6661 notifyPackageUse(mBackupTarget.appInfo.packageName,
6662 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6664 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6665 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6666 mBackupTarget.backupMode);
6667 } catch (Exception e) {
6668 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6674 app.kill("error during init", true);
6675 handleAppDiedLocked(app, false, true);
6679 if (!didSomething) {
6680 updateOomAdjLocked();
6687 public final void attachApplication(IApplicationThread thread) {
6688 synchronized (this) {
6689 int callingPid = Binder.getCallingPid();
6690 final long origId = Binder.clearCallingIdentity();
6691 attachApplicationLocked(thread, callingPid);
6692 Binder.restoreCallingIdentity(origId);
6697 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6698 final long origId = Binder.clearCallingIdentity();
6699 synchronized (this) {
6700 ActivityStack stack = ActivityRecord.getStackLocked(token);
6701 if (stack != null) {
6703 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6704 if (stopProfiling) {
6705 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6708 } catch (IOException e) {
6710 clearProfilerLocked();
6715 Binder.restoreCallingIdentity(origId);
6718 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6719 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6720 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6723 void enableScreenAfterBoot() {
6724 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6725 SystemClock.uptimeMillis());
6726 mWindowManager.enableScreenAfterBoot();
6728 synchronized (this) {
6729 updateEventDispatchingLocked();
6734 public void showBootMessage(final CharSequence msg, final boolean always) {
6735 if (Binder.getCallingUid() != Process.myUid()) {
6736 throw new SecurityException();
6738 mWindowManager.showBootMessage(msg, always);
6742 public void keyguardWaitingForActivityDrawn() {
6743 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6744 final long token = Binder.clearCallingIdentity();
6746 synchronized (this) {
6747 if (DEBUG_LOCKSCREEN) logLockScreen("");
6748 mWindowManager.keyguardWaitingForActivityDrawn();
6749 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6750 mLockScreenShown = LOCK_SCREEN_LEAVING;
6751 updateSleepIfNeededLocked();
6755 Binder.restoreCallingIdentity(token);
6760 public void keyguardGoingAway(int flags) {
6761 enforceNotIsolatedCaller("keyguardGoingAway");
6762 final long token = Binder.clearCallingIdentity();
6764 synchronized (this) {
6765 if (DEBUG_LOCKSCREEN) logLockScreen("");
6766 mWindowManager.keyguardGoingAway(flags);
6767 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6768 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6769 updateSleepIfNeededLocked();
6771 // Some stack visibility might change (e.g. docked stack)
6772 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6773 applyVrModeIfNeededLocked(mFocusedActivity, true);
6777 Binder.restoreCallingIdentity(token);
6781 final void finishBooting() {
6782 synchronized (this) {
6783 if (!mBootAnimationComplete) {
6784 mCallFinishBooting = true;
6787 mCallFinishBooting = false;
6790 ArraySet<String> completedIsas = new ArraySet<String>();
6791 for (String abi : Build.SUPPORTED_ABIS) {
6792 Process.establishZygoteConnectionForAbi(abi);
6793 final String instructionSet = VMRuntime.getInstructionSet(abi);
6794 if (!completedIsas.contains(instructionSet)) {
6796 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6797 } catch (InstallerException e) {
6798 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6799 e.getMessage() +")");
6801 completedIsas.add(instructionSet);
6805 IntentFilter pkgFilter = new IntentFilter();
6806 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6807 pkgFilter.addDataScheme("package");
6808 mContext.registerReceiver(new BroadcastReceiver() {
6810 public void onReceive(Context context, Intent intent) {
6811 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6813 for (String pkg : pkgs) {
6814 synchronized (ActivityManagerService.this) {
6815 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6816 0, "query restart")) {
6817 setResultCode(Activity.RESULT_OK);
6826 IntentFilter dumpheapFilter = new IntentFilter();
6827 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6828 mContext.registerReceiver(new BroadcastReceiver() {
6830 public void onReceive(Context context, Intent intent) {
6831 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6832 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6834 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6839 // Let system services know.
6840 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6842 synchronized (this) {
6843 // Ensure that any processes we had put on hold are now started
6845 final int NP = mProcessesOnHold.size();
6847 ArrayList<ProcessRecord> procs =
6848 new ArrayList<ProcessRecord>(mProcessesOnHold);
6849 for (int ip=0; ip<NP; ip++) {
6850 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6852 startProcessLocked(procs.get(ip), "on-hold", null);
6856 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6857 // Start looking for apps that are abusing wake locks.
6858 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6859 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6860 // Tell anyone interested that we are done booting!
6861 SystemProperties.set("sys.boot_completed", "1");
6863 // And trigger dev.bootcomplete if we are not showing encryption progress
6864 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6865 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6866 SystemProperties.set("dev.bootcomplete", "1");
6868 mUserController.sendBootCompletedLocked(
6869 new IIntentReceiver.Stub() {
6871 public void performReceive(Intent intent, int resultCode,
6872 String data, Bundle extras, boolean ordered,
6873 boolean sticky, int sendingUser) {
6874 synchronized (ActivityManagerService.this) {
6875 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6880 scheduleStartProfilesLocked();
6886 public void bootAnimationComplete() {
6887 final boolean callFinishBooting;
6888 synchronized (this) {
6889 callFinishBooting = mCallFinishBooting;
6890 mBootAnimationComplete = true;
6892 if (callFinishBooting) {
6893 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6895 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6899 final void ensureBootCompleted() {
6901 boolean enableScreen;
6902 synchronized (this) {
6905 enableScreen = !mBooted;
6910 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6912 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6916 enableScreenAfterBoot();
6921 public final void activityResumed(IBinder token) {
6922 final long origId = Binder.clearCallingIdentity();
6923 synchronized(this) {
6924 ActivityStack stack = ActivityRecord.getStackLocked(token);
6925 if (stack != null) {
6926 stack.activityResumedLocked(token);
6929 Binder.restoreCallingIdentity(origId);
6933 public final void activityPaused(IBinder token) {
6934 final long origId = Binder.clearCallingIdentity();
6935 synchronized(this) {
6936 ActivityStack stack = ActivityRecord.getStackLocked(token);
6937 if (stack != null) {
6938 stack.activityPausedLocked(token, false);
6941 Binder.restoreCallingIdentity(origId);
6945 public final void activityStopped(IBinder token, Bundle icicle,
6946 PersistableBundle persistentState, CharSequence description) {
6947 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6949 // Refuse possible leaked file descriptors
6950 if (icicle != null && icicle.hasFileDescriptors()) {
6951 throw new IllegalArgumentException("File descriptors passed in Bundle");
6954 final long origId = Binder.clearCallingIdentity();
6956 synchronized (this) {
6957 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6959 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6965 Binder.restoreCallingIdentity(origId);
6969 public final void activityDestroyed(IBinder token) {
6970 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6971 synchronized (this) {
6972 ActivityStack stack = ActivityRecord.getStackLocked(token);
6973 if (stack != null) {
6974 stack.activityDestroyedLocked(token, "activityDestroyed");
6980 public final void activityRelaunched(IBinder token) {
6981 final long origId = Binder.clearCallingIdentity();
6982 synchronized (this) {
6983 mStackSupervisor.activityRelaunchedLocked(token);
6985 Binder.restoreCallingIdentity(origId);
6989 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6990 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6991 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6992 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6993 synchronized (this) {
6994 ActivityRecord record = ActivityRecord.isInStackLocked(token);
6995 if (record == null) {
6996 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6997 + "found for: " + token);
6999 record.setSizeConfigurations(horizontalSizeConfiguration,
7000 verticalSizeConfigurations, smallestSizeConfigurations);
7005 public final void backgroundResourcesReleased(IBinder token) {
7006 final long origId = Binder.clearCallingIdentity();
7008 synchronized (this) {
7009 ActivityStack stack = ActivityRecord.getStackLocked(token);
7010 if (stack != null) {
7011 stack.backgroundResourcesReleased();
7015 Binder.restoreCallingIdentity(origId);
7020 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7021 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7025 public final void notifyEnterAnimationComplete(IBinder token) {
7026 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7030 public String getCallingPackage(IBinder token) {
7031 synchronized (this) {
7032 ActivityRecord r = getCallingRecordLocked(token);
7033 return r != null ? r.info.packageName : null;
7038 public ComponentName getCallingActivity(IBinder token) {
7039 synchronized (this) {
7040 ActivityRecord r = getCallingRecordLocked(token);
7041 return r != null ? r.intent.getComponent() : null;
7045 private ActivityRecord getCallingRecordLocked(IBinder token) {
7046 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7054 public ComponentName getActivityClassForToken(IBinder token) {
7055 synchronized(this) {
7056 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7060 return r.intent.getComponent();
7065 public String getPackageForToken(IBinder token) {
7066 synchronized(this) {
7067 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7071 return r.packageName;
7076 public boolean isRootVoiceInteraction(IBinder token) {
7077 synchronized(this) {
7078 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7082 return r.rootVoiceInteraction;
7087 public IIntentSender getIntentSender(int type,
7088 String packageName, IBinder token, String resultWho,
7089 int requestCode, Intent[] intents, String[] resolvedTypes,
7090 int flags, Bundle bOptions, int userId) {
7091 enforceNotIsolatedCaller("getIntentSender");
7092 // Refuse possible leaked file descriptors
7093 if (intents != null) {
7094 if (intents.length < 1) {
7095 throw new IllegalArgumentException("Intents array length must be >= 1");
7097 for (int i=0; i<intents.length; i++) {
7098 Intent intent = intents[i];
7099 if (intent != null) {
7100 if (intent.hasFileDescriptors()) {
7101 throw new IllegalArgumentException("File descriptors passed in Intent");
7103 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7104 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7105 throw new IllegalArgumentException(
7106 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7108 intents[i] = new Intent(intent);
7111 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7112 throw new IllegalArgumentException(
7113 "Intent array length does not match resolvedTypes length");
7116 if (bOptions != null) {
7117 if (bOptions.hasFileDescriptors()) {
7118 throw new IllegalArgumentException("File descriptors passed in options");
7122 synchronized(this) {
7123 int callingUid = Binder.getCallingUid();
7124 int origUserId = userId;
7125 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7126 type == ActivityManager.INTENT_SENDER_BROADCAST,
7127 ALLOW_NON_FULL, "getIntentSender", null);
7128 if (origUserId == UserHandle.USER_CURRENT) {
7129 // We don't want to evaluate this until the pending intent is
7130 // actually executed. However, we do want to always do the
7131 // security checking for it above.
7132 userId = UserHandle.USER_CURRENT;
7135 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7136 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7137 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7138 if (!UserHandle.isSameApp(callingUid, uid)) {
7139 String msg = "Permission Denial: getIntentSender() from pid="
7140 + Binder.getCallingPid()
7141 + ", uid=" + Binder.getCallingUid()
7142 + ", (need uid=" + uid + ")"
7143 + " is not allowed to send as package " + packageName;
7145 throw new SecurityException(msg);
7149 return getIntentSenderLocked(type, packageName, callingUid, userId,
7150 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7152 } catch (RemoteException e) {
7153 throw new SecurityException(e);
7158 IIntentSender getIntentSenderLocked(int type, String packageName,
7159 int callingUid, int userId, IBinder token, String resultWho,
7160 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7162 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7163 ActivityRecord activity = null;
7164 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7165 activity = ActivityRecord.isInStackLocked(token);
7166 if (activity == null) {
7167 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7170 if (activity.finishing) {
7171 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7176 // We're going to be splicing together extras before sending, so we're
7177 // okay poking into any contained extras.
7178 if (intents != null) {
7179 for (int i = 0; i < intents.length; i++) {
7180 intents[i].setDefusable(true);
7183 Bundle.setDefusable(bOptions, true);
7185 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7186 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7187 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7188 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7189 |PendingIntent.FLAG_UPDATE_CURRENT);
7191 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7192 type, packageName, activity, resultWho,
7193 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7194 WeakReference<PendingIntentRecord> ref;
7195 ref = mIntentSenderRecords.get(key);
7196 PendingIntentRecord rec = ref != null ? ref.get() : null;
7198 if (!cancelCurrent) {
7199 if (updateCurrent) {
7200 if (rec.key.requestIntent != null) {
7201 rec.key.requestIntent.replaceExtras(intents != null ?
7202 intents[intents.length - 1] : null);
7204 if (intents != null) {
7205 intents[intents.length-1] = rec.key.requestIntent;
7206 rec.key.allIntents = intents;
7207 rec.key.allResolvedTypes = resolvedTypes;
7209 rec.key.allIntents = null;
7210 rec.key.allResolvedTypes = null;
7215 rec.canceled = true;
7216 mIntentSenderRecords.remove(key);
7221 rec = new PendingIntentRecord(this, key, callingUid);
7222 mIntentSenderRecords.put(key, rec.ref);
7223 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7224 if (activity.pendingResults == null) {
7225 activity.pendingResults
7226 = new HashSet<WeakReference<PendingIntentRecord>>();
7228 activity.pendingResults.add(rec.ref);
7234 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7235 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7236 if (target instanceof PendingIntentRecord) {
7237 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7238 finishedReceiver, requiredPermission, options);
7240 if (intent == null) {
7241 // Weird case: someone has given us their own custom IIntentSender, and now
7242 // they have someone else trying to send to it but of course this isn't
7243 // really a PendingIntent, so there is no base Intent, and the caller isn't
7244 // supplying an Intent... but we never want to dispatch a null Intent to
7245 // a receiver, so um... let's make something up.
7246 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7247 intent = new Intent(Intent.ACTION_MAIN);
7250 target.send(code, intent, resolvedType, null, requiredPermission, options);
7251 } catch (RemoteException e) {
7253 // Platform code can rely on getting a result back when the send is done, but if
7254 // this intent sender is from outside of the system we can't rely on it doing that.
7255 // So instead we don't give it the result receiver, and instead just directly
7256 // report the finish immediately.
7257 if (finishedReceiver != null) {
7259 finishedReceiver.performReceive(intent, 0,
7260 null, null, false, false, UserHandle.getCallingUserId());
7261 } catch (RemoteException e) {
7269 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7271 * <p>{@code callerUid} must be allowed to request such whitelist by calling
7272 * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7274 void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7275 if (DEBUG_WHITELISTS) {
7276 Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7277 + targetUid + ", " + duration + ")");
7279 synchronized (mPidsSelfLocked) {
7280 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7282 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7285 if (!pr.whitelistManager) {
7286 if (DEBUG_WHITELISTS) {
7287 Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7288 + callerPid + " is not allowed");
7294 final long token = Binder.clearCallingIdentity();
7296 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7297 true, "pe from uid:" + callerUid);
7299 Binder.restoreCallingIdentity(token);
7304 public void cancelIntentSender(IIntentSender sender) {
7305 if (!(sender instanceof PendingIntentRecord)) {
7308 synchronized(this) {
7309 PendingIntentRecord rec = (PendingIntentRecord)sender;
7311 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7312 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7313 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7314 String msg = "Permission Denial: cancelIntentSender() from pid="
7315 + Binder.getCallingPid()
7316 + ", uid=" + Binder.getCallingUid()
7317 + " is not allowed to cancel packges "
7318 + rec.key.packageName;
7320 throw new SecurityException(msg);
7322 } catch (RemoteException e) {
7323 throw new SecurityException(e);
7325 cancelIntentSenderLocked(rec, true);
7329 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7330 rec.canceled = true;
7331 mIntentSenderRecords.remove(rec.key);
7332 if (cleanActivity && rec.key.activity != null) {
7333 rec.key.activity.pendingResults.remove(rec.ref);
7338 public String getPackageForIntentSender(IIntentSender pendingResult) {
7339 if (!(pendingResult instanceof PendingIntentRecord)) {
7343 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7344 return res.key.packageName;
7345 } catch (ClassCastException e) {
7351 public int getUidForIntentSender(IIntentSender sender) {
7352 if (sender instanceof PendingIntentRecord) {
7354 PendingIntentRecord res = (PendingIntentRecord)sender;
7356 } catch (ClassCastException e) {
7363 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7364 if (!(pendingResult instanceof PendingIntentRecord)) {
7368 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7369 if (res.key.allIntents == null) {
7372 for (int i=0; i<res.key.allIntents.length; i++) {
7373 Intent intent = res.key.allIntents[i];
7374 if (intent.getPackage() != null && intent.getComponent() != null) {
7379 } catch (ClassCastException e) {
7385 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7386 if (!(pendingResult instanceof PendingIntentRecord)) {
7390 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7391 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7395 } catch (ClassCastException e) {
7401 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7402 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7403 "getIntentForIntentSender()");
7404 if (!(pendingResult instanceof PendingIntentRecord)) {
7408 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7409 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7410 } catch (ClassCastException e) {
7416 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7417 if (!(pendingResult instanceof PendingIntentRecord)) {
7421 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7422 synchronized (this) {
7423 return getTagForIntentSenderLocked(res, prefix);
7425 } catch (ClassCastException e) {
7430 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7431 final Intent intent = res.key.requestIntent;
7432 if (intent != null) {
7433 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7434 || res.lastTagPrefix.equals(prefix))) {
7437 res.lastTagPrefix = prefix;
7438 final StringBuilder sb = new StringBuilder(128);
7439 if (prefix != null) {
7442 if (intent.getAction() != null) {
7443 sb.append(intent.getAction());
7444 } else if (intent.getComponent() != null) {
7445 intent.getComponent().appendShortString(sb);
7449 return res.lastTag = sb.toString();
7455 public void setProcessLimit(int max) {
7456 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7457 "setProcessLimit()");
7458 synchronized (this) {
7459 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7460 mProcessLimitOverride = max;
7466 public int getProcessLimit() {
7467 synchronized (this) {
7468 return mProcessLimitOverride;
7472 void foregroundTokenDied(ForegroundToken token) {
7473 synchronized (ActivityManagerService.this) {
7474 synchronized (mPidsSelfLocked) {
7476 = mForegroundProcesses.get(token.pid);
7480 mForegroundProcesses.remove(token.pid);
7481 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7485 pr.forcingToForeground = null;
7486 updateProcessForegroundLocked(pr, false, false);
7488 updateOomAdjLocked();
7493 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7494 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7495 "setProcessForeground()");
7496 synchronized(this) {
7497 boolean changed = false;
7499 synchronized (mPidsSelfLocked) {
7500 ProcessRecord pr = mPidsSelfLocked.get(pid);
7501 if (pr == null && isForeground) {
7502 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7505 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7506 if (oldToken != null) {
7507 oldToken.token.unlinkToDeath(oldToken, 0);
7508 mForegroundProcesses.remove(pid);
7510 pr.forcingToForeground = null;
7514 if (isForeground && token != null) {
7515 ForegroundToken newToken = new ForegroundToken() {
7517 public void binderDied() {
7518 foregroundTokenDied(this);
7522 newToken.token = token;
7524 token.linkToDeath(newToken, 0);
7525 mForegroundProcesses.put(pid, newToken);
7526 pr.forcingToForeground = token;
7528 } catch (RemoteException e) {
7529 // If the process died while doing this, we will later
7530 // do the cleanup with the process death link.
7536 updateOomAdjLocked();
7542 public boolean isAppForeground(int uid) throws RemoteException {
7543 synchronized (this) {
7544 UidRecord uidRec = mActiveUids.get(uid);
7545 if (uidRec == null || uidRec.idle) {
7548 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7552 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7553 // be guarded by permission checking.
7554 int getUidState(int uid) {
7555 synchronized (this) {
7556 UidRecord uidRec = mActiveUids.get(uid);
7557 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7562 public boolean isInMultiWindowMode(IBinder token) {
7563 final long origId = Binder.clearCallingIdentity();
7565 synchronized(this) {
7566 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7570 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7571 return !r.task.mFullscreen;
7574 Binder.restoreCallingIdentity(origId);
7579 public boolean isInPictureInPictureMode(IBinder token) {
7580 final long origId = Binder.clearCallingIdentity();
7582 synchronized(this) {
7583 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7584 if (stack == null) {
7587 return stack.mStackId == PINNED_STACK_ID;
7590 Binder.restoreCallingIdentity(origId);
7595 public void enterPictureInPictureMode(IBinder token) {
7596 final long origId = Binder.clearCallingIdentity();
7598 synchronized(this) {
7599 if (!mSupportsPictureInPicture) {
7600 throw new IllegalStateException("enterPictureInPictureMode: "
7601 + "Device doesn't support picture-in-picture mode.");
7604 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7607 throw new IllegalStateException("enterPictureInPictureMode: "
7608 + "Can't find activity for token=" + token);
7611 if (!r.supportsPictureInPicture()) {
7612 throw new IllegalArgumentException("enterPictureInPictureMode: "
7613 + "Picture-In-Picture not supported for r=" + r);
7616 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7618 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7619 final Rect bounds = (pinnedStack != null)
7620 ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7622 mStackSupervisor.moveActivityToPinnedStackLocked(
7623 r, "enterPictureInPictureMode", bounds);
7626 Binder.restoreCallingIdentity(origId);
7630 // =========================================================
7632 // =========================================================
7634 static class ProcessInfoService extends IProcessInfoService.Stub {
7635 final ActivityManagerService mActivityManagerService;
7636 ProcessInfoService(ActivityManagerService activityManagerService) {
7637 mActivityManagerService = activityManagerService;
7641 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7642 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7643 /*in*/ pids, /*out*/ states, null);
7647 public void getProcessStatesAndOomScoresFromPids(
7648 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7649 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7650 /*in*/ pids, /*out*/ states, /*out*/ scores);
7655 * For each PID in the given input array, write the current process state
7656 * for that process into the states array, or -1 to indicate that no
7657 * process with the given PID exists. If scores array is provided, write
7658 * the oom score for the process into the scores array, with INVALID_ADJ
7659 * indicating the PID doesn't exist.
7661 public void getProcessStatesAndOomScoresForPIDs(
7662 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7663 if (scores != null) {
7664 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7665 "getProcessStatesAndOomScoresForPIDs()");
7669 throw new NullPointerException("pids");
7670 } else if (states == null) {
7671 throw new NullPointerException("states");
7672 } else if (pids.length != states.length) {
7673 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7674 } else if (scores != null && pids.length != scores.length) {
7675 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7678 synchronized (mPidsSelfLocked) {
7679 for (int i = 0; i < pids.length; i++) {
7680 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7681 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7683 if (scores != null) {
7684 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7690 // =========================================================
7692 // =========================================================
7694 static class PermissionController extends IPermissionController.Stub {
7695 ActivityManagerService mActivityManagerService;
7696 PermissionController(ActivityManagerService activityManagerService) {
7697 mActivityManagerService = activityManagerService;
7701 public boolean checkPermission(String permission, int pid, int uid) {
7702 return mActivityManagerService.checkPermission(permission, pid,
7703 uid) == PackageManager.PERMISSION_GRANTED;
7707 public String[] getPackagesForUid(int uid) {
7708 return mActivityManagerService.mContext.getPackageManager()
7709 .getPackagesForUid(uid);
7713 public boolean isRuntimePermission(String permission) {
7715 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7716 .getPermissionInfo(permission, 0);
7717 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7718 } catch (NameNotFoundException nnfe) {
7719 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7725 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7727 public int checkComponentPermission(String permission, int pid, int uid,
7728 int owningUid, boolean exported) {
7729 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7730 owningUid, exported);
7734 public Object getAMSLock() {
7735 return ActivityManagerService.this;
7740 * This can be called with or without the global lock held.
7742 int checkComponentPermission(String permission, int pid, int uid,
7743 int owningUid, boolean exported) {
7744 if (pid == MY_PID) {
7745 return PackageManager.PERMISSION_GRANTED;
7747 return ActivityManager.checkComponentPermission(permission, uid,
7748 owningUid, exported);
7752 * As the only public entry point for permissions checking, this method
7753 * can enforce the semantic that requesting a check on a null global
7754 * permission is automatically denied. (Internally a null permission
7755 * string is used when calling {@link #checkComponentPermission} in cases
7756 * when only uid-based security is needed.)
7758 * This can be called with or without the global lock held.
7761 public int checkPermission(String permission, int pid, int uid) {
7762 if (permission == null) {
7763 return PackageManager.PERMISSION_DENIED;
7765 return checkComponentPermission(permission, pid, uid, -1, true);
7769 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7770 if (permission == null) {
7771 return PackageManager.PERMISSION_DENIED;
7774 // We might be performing an operation on behalf of an indirect binder
7775 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7776 // client identity accordingly before proceeding.
7777 Identity tlsIdentity = sCallerIdentity.get();
7778 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7779 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7780 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7781 uid = tlsIdentity.uid;
7782 pid = tlsIdentity.pid;
7785 return checkComponentPermission(permission, pid, uid, -1, true);
7789 * Binder IPC calls go through the public entry point.
7790 * This can be called with or without the global lock held.
7792 int checkCallingPermission(String permission) {
7793 return checkPermission(permission,
7794 Binder.getCallingPid(),
7795 UserHandle.getAppId(Binder.getCallingUid()));
7799 * This can be called with or without the global lock held.
7801 void enforceCallingPermission(String permission, String func) {
7802 if (checkCallingPermission(permission)
7803 == PackageManager.PERMISSION_GRANTED) {
7807 String msg = "Permission Denial: " + func + " from pid="
7808 + Binder.getCallingPid()
7809 + ", uid=" + Binder.getCallingUid()
7810 + " requires " + permission;
7812 throw new SecurityException(msg);
7816 * Determine if UID is holding permissions required to access {@link Uri} in
7817 * the given {@link ProviderInfo}. Final permission checking is always done
7818 * in {@link ContentProvider}.
7820 private final boolean checkHoldingPermissionsLocked(
7821 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7822 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7823 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7824 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7825 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7826 != PERMISSION_GRANTED) {
7830 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7833 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7834 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7835 if (pi.applicationInfo.uid == uid) {
7837 } else if (!pi.exported) {
7841 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7842 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7844 // check if target holds top-level <provider> permissions
7845 if (!readMet && pi.readPermission != null && considerUidPermissions
7846 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7849 if (!writeMet && pi.writePermission != null && considerUidPermissions
7850 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7854 // track if unprotected read/write is allowed; any denied
7855 // <path-permission> below removes this ability
7856 boolean allowDefaultRead = pi.readPermission == null;
7857 boolean allowDefaultWrite = pi.writePermission == null;
7859 // check if target holds any <path-permission> that match uri
7860 final PathPermission[] pps = pi.pathPermissions;
7862 final String path = grantUri.uri.getPath();
7864 while (i > 0 && (!readMet || !writeMet)) {
7866 PathPermission pp = pps[i];
7867 if (pp.match(path)) {
7869 final String pprperm = pp.getReadPermission();
7870 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7871 "Checking read perm for " + pprperm + " for " + pp.getPath()
7872 + ": match=" + pp.match(path)
7873 + " check=" + pm.checkUidPermission(pprperm, uid));
7874 if (pprperm != null) {
7875 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7876 == PERMISSION_GRANTED) {
7879 allowDefaultRead = false;
7884 final String ppwperm = pp.getWritePermission();
7885 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7886 "Checking write perm " + ppwperm + " for " + pp.getPath()
7887 + ": match=" + pp.match(path)
7888 + " check=" + pm.checkUidPermission(ppwperm, uid));
7889 if (ppwperm != null) {
7890 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7891 == PERMISSION_GRANTED) {
7894 allowDefaultWrite = false;
7902 // grant unprotected <provider> read/write, if not blocked by
7903 // <path-permission> above
7904 if (allowDefaultRead) readMet = true;
7905 if (allowDefaultWrite) writeMet = true;
7907 } catch (RemoteException e) {
7911 return readMet && writeMet;
7914 public int getAppStartMode(int uid, String packageName) {
7915 synchronized (this) {
7916 return checkAllowBackgroundLocked(uid, packageName, -1, true);
7920 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7921 boolean allowWhenForeground) {
7922 UidRecord uidRec = mActiveUids.get(uid);
7923 if (!mLenientBackgroundCheck) {
7924 if (!allowWhenForeground || uidRec == null
7925 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7926 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7927 packageName) != AppOpsManager.MODE_ALLOWED) {
7928 return ActivityManager.APP_START_MODE_DELAYED;
7932 } else if (uidRec == null || uidRec.idle) {
7933 if (callingPid >= 0) {
7935 synchronized (mPidsSelfLocked) {
7936 proc = mPidsSelfLocked.get(callingPid);
7938 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7939 // Whoever is instigating this is in the foreground, so we will allow it
7941 return ActivityManager.APP_START_MODE_NORMAL;
7944 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7945 != AppOpsManager.MODE_ALLOWED) {
7946 return ActivityManager.APP_START_MODE_DELAYED;
7949 return ActivityManager.APP_START_MODE_NORMAL;
7952 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7953 ProviderInfo pi = null;
7954 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7959 pi = AppGlobals.getPackageManager().resolveContentProvider(
7960 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7962 } catch (RemoteException ex) {
7968 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7969 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7970 if (targetUris != null) {
7971 return targetUris.get(grantUri);
7976 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7977 String targetPkg, int targetUid, GrantUri grantUri) {
7978 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7979 if (targetUris == null) {
7980 targetUris = Maps.newArrayMap();
7981 mGrantedUriPermissions.put(targetUid, targetUris);
7984 UriPermission perm = targetUris.get(grantUri);
7986 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7987 targetUris.put(grantUri, perm);
7993 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7994 final int modeFlags) {
7995 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7996 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7997 : UriPermission.STRENGTH_OWNED;
7999 // Root gets to do everything.
8004 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8005 if (perms == null) return false;
8007 // First look for exact match
8008 final UriPermission exactPerm = perms.get(grantUri);
8009 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8013 // No exact match, look for prefixes
8014 final int N = perms.size();
8015 for (int i = 0; i < N; i++) {
8016 final UriPermission perm = perms.valueAt(i);
8017 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8018 && perm.getStrength(modeFlags) >= minStrength) {
8027 * @param uri This uri must NOT contain an embedded userId.
8028 * @param userId The userId in which the uri is to be resolved.
8031 public int checkUriPermission(Uri uri, int pid, int uid,
8032 final int modeFlags, int userId, IBinder callerToken) {
8033 enforceNotIsolatedCaller("checkUriPermission");
8035 // Another redirected-binder-call permissions check as in
8036 // {@link checkPermissionWithToken}.
8037 Identity tlsIdentity = sCallerIdentity.get();
8038 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8039 uid = tlsIdentity.uid;
8040 pid = tlsIdentity.pid;
8043 // Our own process gets to do everything.
8044 if (pid == MY_PID) {
8045 return PackageManager.PERMISSION_GRANTED;
8047 synchronized (this) {
8048 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8049 ? PackageManager.PERMISSION_GRANTED
8050 : PackageManager.PERMISSION_DENIED;
8055 * Check if the targetPkg can be granted permission to access uri by
8056 * the callingUid using the given modeFlags. Throws a security exception
8057 * if callingUid is not allowed to do this. Returns the uid of the target
8058 * if the URI permission grant should be performed; returns -1 if it is not
8059 * needed (for example targetPkg already has permission to access the URI).
8060 * If you already know the uid of the target, you can supply it in
8061 * lastTargetUid else set that to -1.
8063 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8064 final int modeFlags, int lastTargetUid) {
8065 if (!Intent.isAccessUriMode(modeFlags)) {
8069 if (targetPkg != null) {
8070 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8071 "Checking grant " + targetPkg + " permission to " + grantUri);
8074 final IPackageManager pm = AppGlobals.getPackageManager();
8076 // If this is not a content: uri, we can't do anything with it.
8077 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8078 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079 "Can't grant URI permission for non-content URI: " + grantUri);
8083 final String authority = grantUri.uri.getAuthority();
8084 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8085 MATCH_DEBUG_TRIAGED_MISSING);
8087 Slog.w(TAG, "No content provider found for permission check: " +
8088 grantUri.uri.toSafeString());
8092 int targetUid = lastTargetUid;
8093 if (targetUid < 0 && targetPkg != null) {
8095 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8096 UserHandle.getUserId(callingUid));
8097 if (targetUid < 0) {
8098 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099 "Can't grant URI permission no uid for: " + targetPkg);
8102 } catch (RemoteException ex) {
8107 if (targetUid >= 0) {
8108 // First... does the target actually need this permission?
8109 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8110 // No need to grant the target this permission.
8111 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8112 "Target " + targetPkg + " already has full permission to " + grantUri);
8116 // First... there is no target package, so can anyone access it?
8117 boolean allowed = pi.exported;
8118 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8119 if (pi.readPermission != null) {
8123 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8124 if (pi.writePermission != null) {
8133 /* There is a special cross user grant if:
8134 * - The target is on another user.
8135 * - Apps on the current user can access the uri without any uid permissions.
8136 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8137 * grant uri permissions.
8139 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8140 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8141 modeFlags, false /*without considering the uid permissions*/);
8143 // Second... is the provider allowing granting of URI permissions?
8144 if (!specialCrossUserGrant) {
8145 if (!pi.grantUriPermissions) {
8146 throw new SecurityException("Provider " + pi.packageName
8148 + " does not allow granting of Uri permissions (uri "
8151 if (pi.uriPermissionPatterns != null) {
8152 final int N = pi.uriPermissionPatterns.length;
8153 boolean allowed = false;
8154 for (int i=0; i<N; i++) {
8155 if (pi.uriPermissionPatterns[i] != null
8156 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8162 throw new SecurityException("Provider " + pi.packageName
8164 + " does not allow granting of permission to path of Uri "
8170 // Third... does the caller itself have permission to access
8172 final int callingAppId = UserHandle.getAppId(callingUid);
8173 if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8174 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8175 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8178 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8179 // Require they hold a strong enough Uri permission
8180 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8181 throw new SecurityException("Uid " + callingUid
8182 + " does not have permission to uri " + grantUri);
8190 * @param uri This uri must NOT contain an embedded userId.
8191 * @param userId The userId in which the uri is to be resolved.
8194 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8195 final int modeFlags, int userId) {
8196 enforceNotIsolatedCaller("checkGrantUriPermission");
8197 synchronized(this) {
8198 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8199 new GrantUri(userId, uri, false), modeFlags, -1);
8203 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8204 final int modeFlags, UriPermissionOwner owner) {
8205 if (!Intent.isAccessUriMode(modeFlags)) {
8209 // So here we are: the caller has the assumed permission
8210 // to the uri, and the target doesn't. Let's now give this to
8213 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8214 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8216 final String authority = grantUri.uri.getAuthority();
8217 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8218 MATCH_DEBUG_TRIAGED_MISSING);
8220 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8224 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8225 grantUri.prefix = true;
8227 final UriPermission perm = findOrCreateUriPermissionLocked(
8228 pi.packageName, targetPkg, targetUid, grantUri);
8229 perm.grantModes(modeFlags, owner);
8232 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8233 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8234 if (targetPkg == null) {
8235 throw new NullPointerException("targetPkg");
8238 final IPackageManager pm = AppGlobals.getPackageManager();
8240 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8241 } catch (RemoteException ex) {
8245 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8247 if (targetUid < 0) {
8251 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8255 static class NeededUriGrants extends ArrayList<GrantUri> {
8256 final String targetPkg;
8257 final int targetUid;
8260 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8261 this.targetPkg = targetPkg;
8262 this.targetUid = targetUid;
8268 * Like checkGrantUriPermissionLocked, but takes an Intent.
8270 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8271 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8272 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8273 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8274 + " clip=" + (intent != null ? intent.getClipData() : null)
8275 + " from " + intent + "; flags=0x"
8276 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8278 if (targetPkg == null) {
8279 throw new NullPointerException("targetPkg");
8282 if (intent == null) {
8285 Uri data = intent.getData();
8286 ClipData clip = intent.getClipData();
8287 if (data == null && clip == null) {
8290 // Default userId for uris in the intent (if they don't specify it themselves)
8291 int contentUserHint = intent.getContentUserHint();
8292 if (contentUserHint == UserHandle.USER_CURRENT) {
8293 contentUserHint = UserHandle.getUserId(callingUid);
8295 final IPackageManager pm = AppGlobals.getPackageManager();
8297 if (needed != null) {
8298 targetUid = needed.targetUid;
8301 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8303 } catch (RemoteException ex) {
8306 if (targetUid < 0) {
8307 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8308 "Can't grant URI permission no uid for: " + targetPkg
8309 + " on user " + targetUserId);
8314 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8315 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8317 if (targetUid > 0) {
8318 if (needed == null) {
8319 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8321 needed.add(grantUri);
8325 for (int i=0; i<clip.getItemCount(); i++) {
8326 Uri uri = clip.getItemAt(i).getUri();
8328 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8329 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8331 if (targetUid > 0) {
8332 if (needed == null) {
8333 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8335 needed.add(grantUri);
8338 Intent clipIntent = clip.getItemAt(i).getIntent();
8339 if (clipIntent != null) {
8340 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8341 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8342 if (newNeeded != null) {
8354 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8356 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8357 UriPermissionOwner owner) {
8358 if (needed != null) {
8359 for (int i=0; i<needed.size(); i++) {
8360 GrantUri grantUri = needed.get(i);
8361 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8362 grantUri, needed.flags, owner);
8367 void grantUriPermissionFromIntentLocked(int callingUid,
8368 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8369 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8370 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8371 if (needed == null) {
8375 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8379 * @param uri This uri must NOT contain an embedded userId.
8380 * @param userId The userId in which the uri is to be resolved.
8383 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8384 final int modeFlags, int userId) {
8385 enforceNotIsolatedCaller("grantUriPermission");
8386 GrantUri grantUri = new GrantUri(userId, uri, false);
8387 synchronized(this) {
8388 final ProcessRecord r = getRecordForAppLocked(caller);
8390 throw new SecurityException("Unable to find app for caller "
8392 + " when granting permission to uri " + grantUri);
8394 if (targetPkg == null) {
8395 throw new IllegalArgumentException("null target");
8397 if (grantUri == null) {
8398 throw new IllegalArgumentException("null uri");
8401 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8402 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8403 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8404 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8406 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8407 UserHandle.getUserId(r.uid));
8411 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8412 if (perm.modeFlags == 0) {
8413 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8415 if (perms != null) {
8416 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8417 "Removing " + perm.targetUid + " permission to " + perm.uri);
8419 perms.remove(perm.uri);
8420 if (perms.isEmpty()) {
8421 mGrantedUriPermissions.remove(perm.targetUid);
8427 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8428 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8429 "Revoking all granted permissions to " + grantUri);
8431 final IPackageManager pm = AppGlobals.getPackageManager();
8432 final String authority = grantUri.uri.getAuthority();
8433 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8434 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8436 Slog.w(TAG, "No content provider found for permission revoke: "
8437 + grantUri.toSafeString());
8441 // Does the caller have this permission on the URI?
8442 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8443 // If they don't have direct access to the URI, then revoke any
8444 // ownerless URI permissions that have been granted to them.
8445 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8446 if (perms != null) {
8447 boolean persistChanged = false;
8448 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8449 final UriPermission perm = it.next();
8450 if (perm.uri.sourceUserId == grantUri.sourceUserId
8451 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8452 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8453 "Revoking non-owned " + perm.targetUid
8454 + " permission to " + perm.uri);
8455 persistChanged |= perm.revokeModes(
8456 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8457 if (perm.modeFlags == 0) {
8462 if (perms.isEmpty()) {
8463 mGrantedUriPermissions.remove(callingUid);
8465 if (persistChanged) {
8466 schedulePersistUriGrants();
8472 boolean persistChanged = false;
8474 // Go through all of the permissions and remove any that match.
8475 int N = mGrantedUriPermissions.size();
8476 for (int i = 0; i < N; i++) {
8477 final int targetUid = mGrantedUriPermissions.keyAt(i);
8478 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8480 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8481 final UriPermission perm = it.next();
8482 if (perm.uri.sourceUserId == grantUri.sourceUserId
8483 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8484 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8485 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8486 persistChanged |= perm.revokeModes(
8487 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8488 if (perm.modeFlags == 0) {
8494 if (perms.isEmpty()) {
8495 mGrantedUriPermissions.remove(targetUid);
8501 if (persistChanged) {
8502 schedulePersistUriGrants();
8507 * @param uri This uri must NOT contain an embedded userId.
8508 * @param userId The userId in which the uri is to be resolved.
8511 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8513 enforceNotIsolatedCaller("revokeUriPermission");
8514 synchronized(this) {
8515 final ProcessRecord r = getRecordForAppLocked(caller);
8517 throw new SecurityException("Unable to find app for caller "
8519 + " when revoking permission to uri " + uri);
8522 Slog.w(TAG, "revokeUriPermission: null uri");
8526 if (!Intent.isAccessUriMode(modeFlags)) {
8530 final String authority = uri.getAuthority();
8531 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8532 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8534 Slog.w(TAG, "No content provider found for permission revoke: "
8535 + uri.toSafeString());
8539 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8544 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8547 * @param packageName Package name to match, or {@code null} to apply to all
8549 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8551 * @param persistable If persistable grants should be removed.
8553 private void removeUriPermissionsForPackageLocked(
8554 String packageName, int userHandle, boolean persistable) {
8555 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8556 throw new IllegalArgumentException("Must narrow by either package or user");
8559 boolean persistChanged = false;
8561 int N = mGrantedUriPermissions.size();
8562 for (int i = 0; i < N; i++) {
8563 final int targetUid = mGrantedUriPermissions.keyAt(i);
8564 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8566 // Only inspect grants matching user
8567 if (userHandle == UserHandle.USER_ALL
8568 || userHandle == UserHandle.getUserId(targetUid)) {
8569 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8570 final UriPermission perm = it.next();
8572 // Only inspect grants matching package
8573 if (packageName == null || perm.sourcePkg.equals(packageName)
8574 || perm.targetPkg.equals(packageName)) {
8575 // Hacky solution as part of fixing a security bug; ignore
8576 // grants associated with DownloadManager so we don't have
8577 // to immediately launch it to regrant the permissions
8578 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8579 && !persistable) continue;
8581 persistChanged |= perm.revokeModes(persistable
8582 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8584 // Only remove when no modes remain; any persisted grants
8585 // will keep this alive.
8586 if (perm.modeFlags == 0) {
8592 if (perms.isEmpty()) {
8593 mGrantedUriPermissions.remove(targetUid);
8600 if (persistChanged) {
8601 schedulePersistUriGrants();
8606 public IBinder newUriPermissionOwner(String name) {
8607 enforceNotIsolatedCaller("newUriPermissionOwner");
8608 synchronized(this) {
8609 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8610 return owner.getExternalTokenLocked();
8615 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8616 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8617 synchronized(this) {
8618 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8620 throw new IllegalArgumentException("Activity does not exist; token="
8623 return r.getUriPermissionsLocked().getExternalTokenLocked();
8627 * @param uri This uri must NOT contain an embedded userId.
8628 * @param sourceUserId The userId in which the uri is to be resolved.
8629 * @param targetUserId The userId of the app that receives the grant.
8632 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8633 final int modeFlags, int sourceUserId, int targetUserId) {
8634 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8635 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8636 "grantUriPermissionFromOwner", null);
8637 synchronized(this) {
8638 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8639 if (owner == null) {
8640 throw new IllegalArgumentException("Unknown owner: " + token);
8642 if (fromUid != Binder.getCallingUid()) {
8643 if (Binder.getCallingUid() != Process.myUid()) {
8644 // Only system code can grant URI permissions on behalf
8646 throw new SecurityException("nice try");
8649 if (targetPkg == null) {
8650 throw new IllegalArgumentException("null target");
8653 throw new IllegalArgumentException("null uri");
8656 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8657 modeFlags, owner, targetUserId);
8662 * @param uri This uri must NOT contain an embedded userId.
8663 * @param userId The userId in which the uri is to be resolved.
8666 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8667 synchronized(this) {
8668 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8669 if (owner == null) {
8670 throw new IllegalArgumentException("Unknown owner: " + token);
8674 owner.removeUriPermissionsLocked(mode);
8676 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8677 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8682 private void schedulePersistUriGrants() {
8683 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8684 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8685 10 * DateUtils.SECOND_IN_MILLIS);
8689 private void writeGrantedUriPermissions() {
8690 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8692 // Snapshot permissions so we can persist without lock
8693 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8694 synchronized (this) {
8695 final int size = mGrantedUriPermissions.size();
8696 for (int i = 0; i < size; i++) {
8697 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8698 for (UriPermission perm : perms.values()) {
8699 if (perm.persistedModeFlags != 0) {
8700 persist.add(perm.snapshot());
8706 FileOutputStream fos = null;
8708 fos = mGrantFile.startWrite();
8710 XmlSerializer out = new FastXmlSerializer();
8711 out.setOutput(fos, StandardCharsets.UTF_8.name());
8712 out.startDocument(null, true);
8713 out.startTag(null, TAG_URI_GRANTS);
8714 for (UriPermission.Snapshot perm : persist) {
8715 out.startTag(null, TAG_URI_GRANT);
8716 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8717 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8718 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8719 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8720 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8721 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8722 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8723 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8724 out.endTag(null, TAG_URI_GRANT);
8726 out.endTag(null, TAG_URI_GRANTS);
8729 mGrantFile.finishWrite(fos);
8730 } catch (IOException e) {
8732 mGrantFile.failWrite(fos);
8737 private void readGrantedUriPermissionsLocked() {
8738 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8740 final long now = System.currentTimeMillis();
8742 FileInputStream fis = null;
8744 fis = mGrantFile.openRead();
8745 final XmlPullParser in = Xml.newPullParser();
8746 in.setInput(fis, StandardCharsets.UTF_8.name());
8749 while ((type = in.next()) != END_DOCUMENT) {
8750 final String tag = in.getName();
8751 if (type == START_TAG) {
8752 if (TAG_URI_GRANT.equals(tag)) {
8753 final int sourceUserId;
8754 final int targetUserId;
8755 final int userHandle = readIntAttribute(in,
8756 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8757 if (userHandle != UserHandle.USER_NULL) {
8758 // For backwards compatibility.
8759 sourceUserId = userHandle;
8760 targetUserId = userHandle;
8762 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8763 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8765 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8766 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8767 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8768 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8769 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8770 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8772 // Sanity check that provider still belongs to source package
8773 // Both direct boot aware and unaware packages are fine as we
8774 // will do filtering at query time to avoid multiple parsing.
8775 final ProviderInfo pi = getProviderInfoLocked(
8776 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8777 | MATCH_DIRECT_BOOT_UNAWARE);
8778 if (pi != null && sourcePkg.equals(pi.packageName)) {
8781 targetUid = AppGlobals.getPackageManager().getPackageUid(
8782 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8783 } catch (RemoteException e) {
8785 if (targetUid != -1) {
8786 final UriPermission perm = findOrCreateUriPermissionLocked(
8787 sourcePkg, targetPkg, targetUid,
8788 new GrantUri(sourceUserId, uri, prefix));
8789 perm.initPersistedModes(modeFlags, createdTime);
8792 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8793 + " but instead found " + pi);
8798 } catch (FileNotFoundException e) {
8799 // Missing grants is okay
8800 } catch (IOException e) {
8801 Slog.wtf(TAG, "Failed reading Uri grants", e);
8802 } catch (XmlPullParserException e) {
8803 Slog.wtf(TAG, "Failed reading Uri grants", e);
8805 IoUtils.closeQuietly(fis);
8810 * @param uri This uri must NOT contain an embedded userId.
8811 * @param userId The userId in which the uri is to be resolved.
8814 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8815 enforceNotIsolatedCaller("takePersistableUriPermission");
8817 Preconditions.checkFlagsArgument(modeFlags,
8818 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8820 synchronized (this) {
8821 final int callingUid = Binder.getCallingUid();
8822 boolean persistChanged = false;
8823 GrantUri grantUri = new GrantUri(userId, uri, false);
8825 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8826 new GrantUri(userId, uri, false));
8827 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8828 new GrantUri(userId, uri, true));
8830 final boolean exactValid = (exactPerm != null)
8831 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8832 final boolean prefixValid = (prefixPerm != null)
8833 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8835 if (!(exactValid || prefixValid)) {
8836 throw new SecurityException("No persistable permission grants found for UID "
8837 + callingUid + " and Uri " + grantUri.toSafeString());
8841 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8844 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8847 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8849 if (persistChanged) {
8850 schedulePersistUriGrants();
8856 * @param uri This uri must NOT contain an embedded userId.
8857 * @param userId The userId in which the uri is to be resolved.
8860 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8861 enforceNotIsolatedCaller("releasePersistableUriPermission");
8863 Preconditions.checkFlagsArgument(modeFlags,
8864 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8866 synchronized (this) {
8867 final int callingUid = Binder.getCallingUid();
8868 boolean persistChanged = false;
8870 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8871 new GrantUri(userId, uri, false));
8872 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8873 new GrantUri(userId, uri, true));
8874 if (exactPerm == null && prefixPerm == null) {
8875 throw new SecurityException("No permission grants found for UID " + callingUid
8876 + " and Uri " + uri.toSafeString());
8879 if (exactPerm != null) {
8880 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8881 removeUriPermissionIfNeededLocked(exactPerm);
8883 if (prefixPerm != null) {
8884 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8885 removeUriPermissionIfNeededLocked(prefixPerm);
8888 if (persistChanged) {
8889 schedulePersistUriGrants();
8895 * Prune any older {@link UriPermission} for the given UID until outstanding
8896 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8898 * @return if any mutations occured that require persisting.
8900 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8901 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8902 if (perms == null) return false;
8903 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8905 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8906 for (UriPermission perm : perms.values()) {
8907 if (perm.persistedModeFlags != 0) {
8908 persisted.add(perm);
8912 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8913 if (trimCount <= 0) return false;
8915 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8916 for (int i = 0; i < trimCount; i++) {
8917 final UriPermission perm = persisted.get(i);
8919 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8920 "Trimming grant created at " + perm.persistedCreateTime);
8922 perm.releasePersistableModes(~0);
8923 removeUriPermissionIfNeededLocked(perm);
8930 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8931 String packageName, boolean incoming) {
8932 enforceNotIsolatedCaller("getPersistedUriPermissions");
8933 Preconditions.checkNotNull(packageName, "packageName");
8935 final int callingUid = Binder.getCallingUid();
8936 final int callingUserId = UserHandle.getUserId(callingUid);
8937 final IPackageManager pm = AppGlobals.getPackageManager();
8939 final int packageUid = pm.getPackageUid(packageName,
8940 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8941 if (packageUid != callingUid) {
8942 throw new SecurityException(
8943 "Package " + packageName + " does not belong to calling UID " + callingUid);
8945 } catch (RemoteException e) {
8946 throw new SecurityException("Failed to verify package name ownership");
8949 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8950 synchronized (this) {
8952 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8954 if (perms == null) {
8955 Slog.w(TAG, "No permission grants found for " + packageName);
8957 for (UriPermission perm : perms.values()) {
8958 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8959 result.add(perm.buildPersistedPublicApiObject());
8964 final int size = mGrantedUriPermissions.size();
8965 for (int i = 0; i < size; i++) {
8966 final ArrayMap<GrantUri, UriPermission> perms =
8967 mGrantedUriPermissions.valueAt(i);
8968 for (UriPermission perm : perms.values()) {
8969 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8970 result.add(perm.buildPersistedPublicApiObject());
8976 return new ParceledListSlice<android.content.UriPermission>(result);
8980 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8981 String packageName, int userId) {
8982 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8983 "getGrantedUriPermissions");
8985 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8986 synchronized (this) {
8987 final int size = mGrantedUriPermissions.size();
8988 for (int i = 0; i < size; i++) {
8989 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8990 for (UriPermission perm : perms.values()) {
8991 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8992 && perm.persistedModeFlags != 0) {
8993 result.add(perm.buildPersistedPublicApiObject());
8998 return new ParceledListSlice<android.content.UriPermission>(result);
9002 public void clearGrantedUriPermissions(String packageName, int userId) {
9003 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9004 "clearGrantedUriPermissions");
9005 removeUriPermissionsForPackageLocked(packageName, userId, true);
9009 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9010 synchronized (this) {
9012 who != null ? getRecordForAppLocked(who) : null;
9013 if (app == null) return;
9015 Message msg = Message.obtain();
9016 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9018 msg.arg1 = waiting ? 1 : 0;
9019 mUiHandler.sendMessage(msg);
9024 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9025 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9026 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9027 outInfo.availMem = Process.getFreeMemory();
9028 outInfo.totalMem = Process.getTotalMemory();
9029 outInfo.threshold = homeAppMem;
9030 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9031 outInfo.hiddenAppThreshold = cachedAppMem;
9032 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9033 ProcessList.SERVICE_ADJ);
9034 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9035 ProcessList.VISIBLE_APP_ADJ);
9036 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9037 ProcessList.FOREGROUND_APP_ADJ);
9040 // =========================================================
9042 // =========================================================
9045 public List<IAppTask> getAppTasks(String callingPackage) {
9046 int callingUid = Binder.getCallingUid();
9047 long ident = Binder.clearCallingIdentity();
9049 synchronized(this) {
9050 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9052 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9054 final int N = mRecentTasks.size();
9055 for (int i = 0; i < N; i++) {
9056 TaskRecord tr = mRecentTasks.get(i);
9057 // Skip tasks that do not match the caller. We don't need to verify
9058 // callingPackage, because we are also limiting to callingUid and know
9059 // that will limit to the correct security sandbox.
9060 if (tr.effectiveUid != callingUid) {
9063 Intent intent = tr.getBaseIntent();
9064 if (intent == null ||
9065 !callingPackage.equals(intent.getComponent().getPackageName())) {
9068 ActivityManager.RecentTaskInfo taskInfo =
9069 createRecentTaskInfoFromTaskRecord(tr);
9070 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9074 Binder.restoreCallingIdentity(ident);
9081 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9082 final int callingUid = Binder.getCallingUid();
9083 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9085 synchronized(this) {
9086 if (DEBUG_ALL) Slog.v(
9087 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9089 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9092 // TODO: Improve with MRU list from all ActivityStacks.
9093 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9100 * Creates a new RecentTaskInfo from a TaskRecord.
9102 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9103 // Update the task description to reflect any changes in the task stack
9104 tr.updateTaskDescription();
9106 // Compose the recent task info
9107 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9108 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9109 rti.persistentId = tr.taskId;
9110 rti.baseIntent = new Intent(tr.getBaseIntent());
9111 rti.origActivity = tr.origActivity;
9112 rti.realActivity = tr.realActivity;
9113 rti.description = tr.lastDescription;
9114 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9115 rti.userId = tr.userId;
9116 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9117 rti.firstActiveTime = tr.firstActiveTime;
9118 rti.lastActiveTime = tr.lastActiveTime;
9119 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9120 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9121 rti.numActivities = 0;
9122 if (tr.mBounds != null) {
9123 rti.bounds = new Rect(tr.mBounds);
9125 rti.isDockable = tr.canGoInDockedStack();
9126 rti.resizeMode = tr.mResizeMode;
9128 ActivityRecord base = null;
9129 ActivityRecord top = null;
9132 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9133 tmp = tr.mActivities.get(i);
9134 if (tmp.finishing) {
9138 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9141 rti.numActivities++;
9144 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9145 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9150 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9151 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9152 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9154 if (checkPermission(android.Manifest.permission.GET_TASKS,
9155 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9156 // Temporary compatibility: some existing apps on the system image may
9157 // still be requesting the old permission and not switched to the new
9158 // one; if so, we'll still allow them full access. This means we need
9159 // to see if they are holding the old permission and are a system app.
9161 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9163 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9164 + " is using old GET_TASKS but privileged; allowing");
9166 } catch (RemoteException e) {
9171 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9172 + " does not hold REAL_GET_TASKS; limiting output");
9178 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9180 final int callingUid = Binder.getCallingUid();
9181 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9182 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9184 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9185 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9186 synchronized (this) {
9187 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9189 final boolean detailed = checkCallingPermission(
9190 android.Manifest.permission.GET_DETAILED_TASKS)
9191 == PackageManager.PERMISSION_GRANTED;
9193 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9194 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9195 return ParceledListSlice.emptyList();
9197 mRecentTasks.loadUserRecentsLocked(userId);
9199 final int recentsCount = mRecentTasks.size();
9200 ArrayList<ActivityManager.RecentTaskInfo> res =
9201 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9203 final Set<Integer> includedUsers;
9204 if (includeProfiles) {
9205 includedUsers = mUserController.getProfileIds(userId);
9207 includedUsers = new HashSet<>();
9209 includedUsers.add(Integer.valueOf(userId));
9211 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9212 TaskRecord tr = mRecentTasks.get(i);
9213 // Only add calling user or related users recent tasks
9214 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9215 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9219 if (tr.realActivitySuspended) {
9220 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9224 // Return the entry if desired by the caller. We always return
9225 // the first entry, because callers always expect this to be the
9226 // foreground app. We may filter others if the caller has
9227 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9228 // we should exclude the entry.
9232 || (tr.intent == null)
9233 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9236 // If the caller doesn't have the GET_TASKS permission, then only
9237 // allow them to see a small subset of tasks -- their own and home.
9238 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9239 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9243 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9244 if (tr.stack != null && tr.stack.isHomeStack()) {
9245 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9246 "Skipping, home stack task: " + tr);
9250 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9251 final ActivityStack stack = tr.stack;
9252 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9253 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9254 "Skipping, top task in docked stack: " + tr);
9258 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9259 if (tr.stack != null && tr.stack.isPinnedStack()) {
9260 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9261 "Skipping, pinned stack task: " + tr);
9265 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9266 // Don't include auto remove tasks that are finished or finishing.
9267 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9268 "Skipping, auto-remove without activity: " + tr);
9271 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9272 && !tr.isAvailable) {
9273 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9274 "Skipping, unavail real act: " + tr);
9278 if (!tr.mUserSetupComplete) {
9279 // Don't include task launched while user is not done setting-up.
9280 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9281 "Skipping, user setup not complete: " + tr);
9285 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9287 rti.baseIntent.replaceExtras((Bundle)null);
9294 return new ParceledListSlice<>(res);
9299 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9300 synchronized (this) {
9301 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9302 "getTaskThumbnail()");
9303 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9304 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9306 return tr.getTaskThumbnailLocked();
9313 public int addAppTask(IBinder activityToken, Intent intent,
9314 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9315 final int callingUid = Binder.getCallingUid();
9316 final long callingIdent = Binder.clearCallingIdentity();
9319 synchronized (this) {
9320 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9322 throw new IllegalArgumentException("Activity does not exist; token="
9325 ComponentName comp = intent.getComponent();
9327 throw new IllegalArgumentException("Intent " + intent
9328 + " must specify explicit component");
9330 if (thumbnail.getWidth() != mThumbnailWidth
9331 || thumbnail.getHeight() != mThumbnailHeight) {
9332 throw new IllegalArgumentException("Bad thumbnail size: got "
9333 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9334 + mThumbnailWidth + "x" + mThumbnailHeight);
9336 if (intent.getSelector() != null) {
9337 intent.setSelector(null);
9339 if (intent.getSourceBounds() != null) {
9340 intent.setSourceBounds(null);
9342 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9343 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9344 // The caller has added this as an auto-remove task... that makes no
9345 // sense, so turn off auto-remove.
9346 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9349 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9350 mLastAddedTaskActivity = null;
9352 ActivityInfo ainfo = mLastAddedTaskActivity;
9353 if (ainfo == null) {
9354 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9355 comp, 0, UserHandle.getUserId(callingUid));
9356 if (ainfo.applicationInfo.uid != callingUid) {
9357 throw new SecurityException(
9358 "Can't add task for another application: target uid="
9359 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9363 // Use the full screen as the context for the task thumbnail
9364 final Point displaySize = new Point();
9365 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9366 r.task.stack.getDisplaySize(displaySize);
9367 thumbnailInfo.taskWidth = displaySize.x;
9368 thumbnailInfo.taskHeight = displaySize.y;
9369 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9371 TaskRecord task = new TaskRecord(this,
9372 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9373 ainfo, intent, description, thumbnailInfo);
9375 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9377 // If this would have caused a trim, then we'll abort because that
9378 // means it would be added at the end of the list but then just removed.
9379 return INVALID_TASK_ID;
9382 final int N = mRecentTasks.size();
9383 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9384 final TaskRecord tr = mRecentTasks.remove(N - 1);
9385 tr.removedFromRecents();
9388 task.inRecents = true;
9389 mRecentTasks.add(task);
9390 r.task.stack.addTask(task, false, "addAppTask");
9392 task.setLastThumbnailLocked(thumbnail);
9393 task.freeLastThumbnail();
9398 Binder.restoreCallingIdentity(callingIdent);
9403 public Point getAppTaskThumbnailSize() {
9404 synchronized (this) {
9405 return new Point(mThumbnailWidth, mThumbnailHeight);
9410 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9411 synchronized (this) {
9412 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9414 r.setTaskDescription(td);
9415 r.task.updateTaskDescription();
9421 public void setTaskResizeable(int taskId, int resizeableMode) {
9422 synchronized (this) {
9423 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9424 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9426 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9429 if (task.mResizeMode != resizeableMode) {
9430 task.mResizeMode = resizeableMode;
9431 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9432 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9433 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9439 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9440 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9441 long ident = Binder.clearCallingIdentity();
9443 synchronized (this) {
9444 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9446 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9449 int stackId = task.stack.mStackId;
9450 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9451 // in crop windows resize mode or if the task size is affected by the docked stack
9452 // changing size. No need to update configuration.
9453 if (bounds != null && task.inCropWindowsResizeMode()
9454 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9455 mWindowManager.scrollTask(task.taskId, bounds);
9459 // Place the task in the right stack if it isn't there already based on
9460 // the requested bounds.
9461 // The stack transition logic is:
9462 // - a null bounds on a freeform task moves that task to fullscreen
9463 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9464 // that task to freeform
9465 // - otherwise the task is not moved
9466 if (!StackId.isTaskResizeAllowed(stackId)) {
9467 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9469 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9470 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9471 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9472 stackId = FREEFORM_WORKSPACE_STACK_ID;
9474 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9475 if (stackId != task.stack.mStackId) {
9476 mStackSupervisor.moveTaskToStackUncheckedLocked(
9477 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9478 preserveWindow = false;
9481 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9482 false /* deferResume */);
9485 Binder.restoreCallingIdentity(ident);
9490 public Rect getTaskBounds(int taskId) {
9491 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9492 long ident = Binder.clearCallingIdentity();
9493 Rect rect = new Rect();
9495 synchronized (this) {
9496 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9497 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9499 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9502 if (task.stack != null) {
9503 // Return the bounds from window manager since it will be adjusted for various
9504 // things like the presense of a docked stack for tasks that aren't resizeable.
9505 mWindowManager.getTaskBounds(task.taskId, rect);
9507 // Task isn't in window manager yet since it isn't associated with a stack.
9508 // Return the persist value from activity manager
9509 if (task.mBounds != null) {
9510 rect.set(task.mBounds);
9511 } else if (task.mLastNonFullscreenBounds != null) {
9512 rect.set(task.mLastNonFullscreenBounds);
9517 Binder.restoreCallingIdentity(ident);
9523 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9524 if (userId != UserHandle.getCallingUserId()) {
9525 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9526 "getTaskDescriptionIcon");
9528 final File passedIconFile = new File(filePath);
9529 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9530 passedIconFile.getName());
9531 if (!legitIconFile.getPath().equals(filePath)
9532 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9533 throw new IllegalArgumentException("Bad file path: " + filePath
9534 + " passed for userId " + userId);
9536 return mRecentTasks.getTaskDescriptionIcon(filePath);
9540 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9541 throws RemoteException {
9542 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9543 opts.getCustomInPlaceResId() == 0) {
9544 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9545 "with valid animation");
9547 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9548 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9549 opts.getCustomInPlaceResId());
9550 mWindowManager.executeAppTransition();
9553 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9554 boolean removeFromRecents) {
9555 if (removeFromRecents) {
9556 mRecentTasks.remove(tr);
9557 tr.removedFromRecents();
9559 ComponentName component = tr.getBaseIntent().getComponent();
9560 if (component == null) {
9561 Slog.w(TAG, "No component for base intent of task: " + tr);
9565 // Find any running services associated with this app and stop if needed.
9566 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9572 // Determine if the process(es) for this task should be killed.
9573 final String pkg = component.getPackageName();
9574 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9575 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9576 for (int i = 0; i < pmap.size(); i++) {
9578 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9579 for (int j = 0; j < uids.size(); j++) {
9580 ProcessRecord proc = uids.valueAt(j);
9581 if (proc.userId != tr.userId) {
9582 // Don't kill process for a different user.
9585 if (proc == mHomeProcess) {
9586 // Don't kill the home process along with tasks from the same package.
9589 if (!proc.pkgList.containsKey(pkg)) {
9590 // Don't kill process that is not associated with this task.
9594 for (int k = 0; k < proc.activities.size(); k++) {
9595 TaskRecord otherTask = proc.activities.get(k).task;
9596 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9597 // Don't kill process(es) that has an activity in a different task that is
9603 if (proc.foregroundServices) {
9604 // Don't kill process(es) with foreground service.
9608 // Add process to kill list.
9609 procsToKill.add(proc);
9613 // Kill the running processes.
9614 for (int i = 0; i < procsToKill.size(); i++) {
9615 ProcessRecord pr = procsToKill.get(i);
9616 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9617 && pr.curReceiver == null) {
9618 pr.kill("remove task", true);
9620 // We delay killing processes that are not in the background or running a receiver.
9621 pr.waitingToKill = "remove task";
9626 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9627 // Remove all tasks with activities in the specified package from the list of recent tasks
9628 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9629 TaskRecord tr = mRecentTasks.get(i);
9630 if (tr.userId != userId) continue;
9632 ComponentName cn = tr.intent.getComponent();
9633 if (cn != null && cn.getPackageName().equals(packageName)) {
9634 // If the package name matches, remove the task.
9635 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9640 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9643 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9644 TaskRecord tr = mRecentTasks.get(i);
9645 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9649 ComponentName cn = tr.intent.getComponent();
9650 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9651 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9652 if (sameComponent) {
9653 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9659 * Removes the task with the specified task id.
9661 * @param taskId Identifier of the task to be removed.
9662 * @param killProcess Kill any process associated with the task if possible.
9663 * @param removeFromRecents Whether to also remove the task from recents.
9664 * @return Returns true if the given task was found and removed.
9666 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9667 boolean removeFromRecents) {
9668 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9669 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9671 tr.removeTaskActivitiesLocked();
9672 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9673 if (tr.isPersistable) {
9674 notifyTaskPersisterLocked(null, true);
9678 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9683 public void removeStack(int stackId) {
9684 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9685 if (stackId == HOME_STACK_ID) {
9686 throw new IllegalArgumentException("Removing home stack is not allowed.");
9689 synchronized (this) {
9690 final long ident = Binder.clearCallingIdentity();
9692 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9693 if (stack == null) {
9696 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9697 for (int i = tasks.size() - 1; i >= 0; i--) {
9698 removeTaskByIdLocked(
9699 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9702 Binder.restoreCallingIdentity(ident);
9708 public boolean removeTask(int taskId) {
9709 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9710 synchronized (this) {
9711 final long ident = Binder.clearCallingIdentity();
9713 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9715 Binder.restoreCallingIdentity(ident);
9721 * TODO: Add mController hook
9724 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9725 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9727 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9728 synchronized(this) {
9729 moveTaskToFrontLocked(taskId, flags, bOptions);
9733 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9734 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9736 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9737 Binder.getCallingUid(), -1, -1, "Task to front")) {
9738 ActivityOptions.abort(options);
9741 final long origId = Binder.clearCallingIdentity();
9743 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9745 Slog.d(TAG, "Could not find task for id: "+ taskId);
9748 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9749 mStackSupervisor.showLockTaskToast();
9750 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9753 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9754 if (prev != null && prev.isRecentsActivity()) {
9755 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9757 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9758 false /* forceNonResizable */);
9760 Binder.restoreCallingIdentity(origId);
9762 ActivityOptions.abort(options);
9766 * Moves an activity, and all of the other activities within the same task, to the bottom
9767 * of the history stack. The activity's order within the task is unchanged.
9769 * @param token A reference to the activity we wish to move
9770 * @param nonRoot If false then this only works if the activity is the root
9771 * of a task; if true it will work for any activity in a task.
9772 * @return Returns true if the move completed, false if not.
9775 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9776 enforceNotIsolatedCaller("moveActivityTaskToBack");
9777 synchronized(this) {
9778 final long origId = Binder.clearCallingIdentity();
9780 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9781 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9783 if (mStackSupervisor.isLockedTask(task)) {
9784 mStackSupervisor.showLockTaskToast();
9787 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9790 Binder.restoreCallingIdentity(origId);
9797 public void moveTaskBackwards(int task) {
9798 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9799 "moveTaskBackwards()");
9801 synchronized(this) {
9802 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9803 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9806 final long origId = Binder.clearCallingIdentity();
9807 moveTaskBackwardsLocked(task);
9808 Binder.restoreCallingIdentity(origId);
9812 private final void moveTaskBackwardsLocked(int task) {
9813 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9817 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9818 IActivityContainerCallback callback) throws RemoteException {
9819 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9820 synchronized (this) {
9821 if (parentActivityToken == null) {
9822 throw new IllegalArgumentException("parent token must not be null");
9824 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9828 if (callback == null) {
9829 throw new IllegalArgumentException("callback must not be null");
9831 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9836 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9837 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9838 synchronized (this) {
9839 mStackSupervisor.deleteActivityContainer(container);
9844 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9845 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9846 synchronized (this) {
9847 final int stackId = mStackSupervisor.getNextStackId();
9848 final ActivityStack stack =
9849 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9850 if (stack == null) {
9853 return stack.mActivityContainer;
9858 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9859 synchronized (this) {
9860 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9861 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9862 return stack.mActivityContainer.getDisplayId();
9864 return Display.DEFAULT_DISPLAY;
9869 public int getActivityStackId(IBinder token) throws RemoteException {
9870 synchronized (this) {
9871 ActivityStack stack = ActivityRecord.getStackLocked(token);
9872 if (stack == null) {
9873 return INVALID_STACK_ID;
9875 return stack.mStackId;
9880 public void exitFreeformMode(IBinder token) throws RemoteException {
9881 synchronized (this) {
9882 long ident = Binder.clearCallingIdentity();
9884 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9886 throw new IllegalArgumentException(
9887 "exitFreeformMode: No activity record matching token=" + token);
9889 final ActivityStack stack = r.getStackLocked(token);
9890 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9891 throw new IllegalStateException(
9892 "exitFreeformMode: You can only go fullscreen from freeform.");
9894 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9895 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9896 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9898 Binder.restoreCallingIdentity(ident);
9904 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9905 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9906 if (stackId == HOME_STACK_ID) {
9907 throw new IllegalArgumentException(
9908 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9910 synchronized (this) {
9911 long ident = Binder.clearCallingIdentity();
9913 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9914 + " to stackId=" + stackId + " toTop=" + toTop);
9915 if (stackId == DOCKED_STACK_ID) {
9916 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9917 null /* initialBounds */);
9919 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9920 !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9921 if (result && stackId == DOCKED_STACK_ID) {
9922 // If task moved to docked stack - show recents if needed.
9923 mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9924 "moveTaskToDockedStack");
9927 Binder.restoreCallingIdentity(ident);
9933 public void swapDockedAndFullscreenStack() throws RemoteException {
9934 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9935 synchronized (this) {
9936 long ident = Binder.clearCallingIdentity();
9938 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9939 FULLSCREEN_WORKSPACE_STACK_ID);
9940 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9942 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9943 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9945 if (topTask == null || tasks == null || tasks.size() == 0) {
9947 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9951 // TODO: App transition
9952 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9954 // Defer the resume so resume/pausing while moving stacks is dangerous.
9955 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9956 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9957 ANIMATE, true /* deferResume */);
9958 final int size = tasks.size();
9959 for (int i = 0; i < size; i++) {
9960 final int id = tasks.get(i).taskId;
9961 if (id == topTask.taskId) {
9964 mStackSupervisor.moveTaskToStackLocked(id,
9965 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9966 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9969 // Because we deferred the resume, to avoid conflicts with stack switches while
9970 // resuming, we need to do it after all the tasks are moved.
9971 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9972 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9974 mWindowManager.executeAppTransition();
9976 Binder.restoreCallingIdentity(ident);
9982 * Moves the input task to the docked stack.
9984 * @param taskId Id of task to move.
9985 * @param createMode The mode the docked stack should be created in if it doesn't exist
9987 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9989 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9990 * @param toTop If the task and stack should be moved to the top.
9991 * @param animate Whether we should play an animation for the moving the task
9992 * @param initialBounds If the docked stack gets created, it will use these bounds for the
9993 * docked stack. Pass {@code null} to use default bounds.
9996 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9997 Rect initialBounds, boolean moveHomeStackFront) {
9998 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9999 synchronized (this) {
10000 long ident = Binder.clearCallingIdentity();
10002 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10003 + " to createMode=" + createMode + " toTop=" + toTop);
10004 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10005 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10006 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10007 animate, DEFER_RESUME);
10009 if (moveHomeStackFront) {
10010 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10012 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10016 Binder.restoreCallingIdentity(ident);
10022 * Moves the top activity in the input stackId to the pinned stack.
10024 * @param stackId Id of stack to move the top activity to pinned stack.
10025 * @param bounds Bounds to use for pinned stack.
10027 * @return True if the top activity of the input stack was successfully moved to the pinned
10031 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10032 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10033 synchronized (this) {
10034 if (!mSupportsPictureInPicture) {
10035 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10036 + "Device doesn't support picture-in-pciture mode");
10039 long ident = Binder.clearCallingIdentity();
10041 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10043 Binder.restoreCallingIdentity(ident);
10049 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10050 boolean preserveWindows, boolean animate, int animationDuration) {
10051 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10052 long ident = Binder.clearCallingIdentity();
10054 synchronized (this) {
10056 if (stackId == PINNED_STACK_ID) {
10057 mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10059 throw new IllegalArgumentException("Stack: " + stackId
10060 + " doesn't support animated resize.");
10063 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10064 null /* tempTaskInsetBounds */, preserveWindows,
10065 allowResizeInDockedMode, !DEFER_RESUME);
10069 Binder.restoreCallingIdentity(ident);
10074 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10075 Rect tempDockedTaskInsetBounds,
10076 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10077 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10078 "resizeDockedStack()");
10079 long ident = Binder.clearCallingIdentity();
10081 synchronized (this) {
10082 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10083 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10087 Binder.restoreCallingIdentity(ident);
10092 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10093 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10094 "resizePinnedStack()");
10095 final long ident = Binder.clearCallingIdentity();
10097 synchronized (this) {
10098 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10101 Binder.restoreCallingIdentity(ident);
10106 public void positionTaskInStack(int taskId, int stackId, int position) {
10107 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10108 if (stackId == HOME_STACK_ID) {
10109 throw new IllegalArgumentException(
10110 "positionTaskInStack: Attempt to change the position of task "
10111 + taskId + " in/to home stack");
10113 synchronized (this) {
10114 long ident = Binder.clearCallingIdentity();
10116 if (DEBUG_STACK) Slog.d(TAG_STACK,
10117 "positionTaskInStack: positioning task=" + taskId
10118 + " in stackId=" + stackId + " at position=" + position);
10119 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10121 Binder.restoreCallingIdentity(ident);
10127 public List<StackInfo> getAllStackInfos() {
10128 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10129 long ident = Binder.clearCallingIdentity();
10131 synchronized (this) {
10132 return mStackSupervisor.getAllStackInfosLocked();
10135 Binder.restoreCallingIdentity(ident);
10140 public StackInfo getStackInfo(int stackId) {
10141 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10142 long ident = Binder.clearCallingIdentity();
10144 synchronized (this) {
10145 return mStackSupervisor.getStackInfoLocked(stackId);
10148 Binder.restoreCallingIdentity(ident);
10153 public boolean isInHomeStack(int taskId) {
10154 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10155 long ident = Binder.clearCallingIdentity();
10157 synchronized (this) {
10158 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10159 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10160 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10163 Binder.restoreCallingIdentity(ident);
10168 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10169 synchronized(this) {
10170 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10175 public void updateDeviceOwner(String packageName) {
10176 final int callingUid = Binder.getCallingUid();
10177 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10178 throw new SecurityException("updateDeviceOwner called from non-system process");
10180 synchronized (this) {
10181 mDeviceOwnerName = packageName;
10186 public void updateLockTaskPackages(int userId, String[] packages) {
10187 final int callingUid = Binder.getCallingUid();
10188 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10189 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10190 "updateLockTaskPackages()");
10192 synchronized (this) {
10193 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10194 Arrays.toString(packages));
10195 mLockTaskPackages.put(userId, packages);
10196 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10201 void startLockTaskModeLocked(TaskRecord task) {
10202 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10203 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10207 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10208 // is initiated by system after the pinning request was shown and locked mode is initiated
10209 // by an authorized app directly
10210 final int callingUid = Binder.getCallingUid();
10211 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10212 long ident = Binder.clearCallingIdentity();
10214 if (!isSystemInitiated) {
10215 task.mLockTaskUid = callingUid;
10216 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10217 // startLockTask() called by app and task mode is lockTaskModeDefault.
10218 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10219 StatusBarManagerInternal statusBarManager =
10220 LocalServices.getService(StatusBarManagerInternal.class);
10221 if (statusBarManager != null) {
10222 statusBarManager.showScreenPinningRequest(task.taskId);
10227 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10228 if (stack == null || task != stack.topTask()) {
10229 throw new IllegalArgumentException("Invalid task, not in foreground");
10232 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10234 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10235 ActivityManager.LOCK_TASK_MODE_PINNED :
10236 ActivityManager.LOCK_TASK_MODE_LOCKED,
10237 "startLockTask", true);
10239 Binder.restoreCallingIdentity(ident);
10244 public void startLockTaskMode(int taskId) {
10245 synchronized (this) {
10246 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10247 if (task != null) {
10248 startLockTaskModeLocked(task);
10254 public void startLockTaskMode(IBinder token) {
10255 synchronized (this) {
10256 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10260 final TaskRecord task = r.task;
10261 if (task != null) {
10262 startLockTaskModeLocked(task);
10268 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10269 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10270 // This makes inner call to look as if it was initiated by system.
10271 long ident = Binder.clearCallingIdentity();
10273 synchronized (this) {
10274 startLockTaskMode(taskId);
10277 Binder.restoreCallingIdentity(ident);
10282 public void stopLockTaskMode() {
10283 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10284 if (lockTask == null) {
10285 // Our work here is done.
10289 final int callingUid = Binder.getCallingUid();
10290 final int lockTaskUid = lockTask.mLockTaskUid;
10291 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10292 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10296 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10297 // It is possible lockTaskMode was started by the system process because
10298 // android:lockTaskMode is set to a locking value in the application manifest
10299 // instead of the app calling startLockTaskMode. In this case
10300 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10301 // {@link TaskRecord.effectiveUid} instead. Also caller with
10302 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10303 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10304 && callingUid != lockTaskUid
10305 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10306 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10307 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10310 long ident = Binder.clearCallingIdentity();
10312 Log.d(TAG, "stopLockTaskMode");
10314 synchronized (this) {
10315 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10316 "stopLockTask", true);
10318 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10320 tm.showInCallScreen(false);
10323 Binder.restoreCallingIdentity(ident);
10328 * This API should be called by SystemUI only when user perform certain action to dismiss
10329 * lock task mode. We should only dismiss pinned lock task mode in this case.
10332 public void stopSystemLockTaskMode() throws RemoteException {
10333 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10334 stopLockTaskMode();
10336 mStackSupervisor.showLockTaskToast();
10341 public boolean isInLockTaskMode() {
10342 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10346 public int getLockTaskModeState() {
10347 synchronized (this) {
10348 return mStackSupervisor.getLockTaskModeState();
10353 public void showLockTaskEscapeMessage(IBinder token) {
10354 synchronized (this) {
10355 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10359 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10363 // =========================================================
10364 // CONTENT PROVIDERS
10365 // =========================================================
10367 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10368 List<ProviderInfo> providers = null;
10370 providers = AppGlobals.getPackageManager()
10371 .queryContentProviders(app.processName, app.uid,
10372 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10373 | MATCH_DEBUG_TRIAGED_MISSING)
10375 } catch (RemoteException ex) {
10377 if (DEBUG_MU) Slog.v(TAG_MU,
10378 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10379 int userId = app.userId;
10380 if (providers != null) {
10381 int N = providers.size();
10382 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10383 for (int i=0; i<N; i++) {
10384 // TODO: keep logic in sync with installEncryptionUnawareProviders
10386 (ProviderInfo)providers.get(i);
10387 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10388 cpi.name, cpi.flags);
10389 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10390 // This is a singleton provider, but a user besides the
10391 // default user is asking to initialize a process it runs
10392 // in... well, no, it doesn't actually run in this process,
10393 // it runs in the process of the default user. Get rid of it.
10394 providers.remove(i);
10400 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10401 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10403 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10404 mProviderMap.putProviderByClass(comp, cpr);
10406 if (DEBUG_MU) Slog.v(TAG_MU,
10407 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10408 app.pubProviders.put(cpi.name, cpr);
10409 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10410 // Don't add this if it is a platform component that is marked
10411 // to run in multiple processes, because this is actually
10412 // part of the framework so doesn't make sense to track as a
10413 // separate apk in the process.
10414 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10417 notifyPackageUse(cpi.applicationInfo.packageName,
10418 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10425 * Check if the calling UID has a possible chance at accessing the provider
10426 * at the given authority and user.
10428 public String checkContentProviderAccess(String authority, int userId) {
10429 if (userId == UserHandle.USER_ALL) {
10430 mContext.enforceCallingOrSelfPermission(
10431 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10432 userId = UserHandle.getCallingUserId();
10435 ProviderInfo cpi = null;
10437 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10438 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10439 | PackageManager.MATCH_DIRECT_BOOT_AWARE
10440 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10442 } catch (RemoteException ignored) {
10445 // TODO: make this an outright failure in a future platform release;
10446 // until then anonymous content notifications are unprotected
10447 //return "Failed to find provider " + authority + " for user " + userId;
10451 ProcessRecord r = null;
10452 synchronized (mPidsSelfLocked) {
10453 r = mPidsSelfLocked.get(Binder.getCallingPid());
10456 return "Failed to find PID " + Binder.getCallingPid();
10459 synchronized (this) {
10460 return checkContentProviderPermissionLocked(cpi, r, userId, true);
10465 * Check if {@link ProcessRecord} has a possible chance at accessing the
10466 * given {@link ProviderInfo}. Final permission checking is always done
10467 * in {@link ContentProvider}.
10469 private final String checkContentProviderPermissionLocked(
10470 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10471 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10472 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10473 boolean checkedGrants = false;
10475 // Looking for cross-user grants before enforcing the typical cross-users permissions
10476 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10477 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10478 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10481 checkedGrants = true;
10483 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10484 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10485 if (userId != tmpTargetUserId) {
10486 // When we actually went to determine the final targer user ID, this ended
10487 // up different than our initial check for the authority. This is because
10488 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10489 // SELF. So we need to re-check the grants again.
10490 checkedGrants = false;
10493 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10494 cpi.applicationInfo.uid, cpi.exported)
10495 == PackageManager.PERMISSION_GRANTED) {
10498 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10499 cpi.applicationInfo.uid, cpi.exported)
10500 == PackageManager.PERMISSION_GRANTED) {
10504 PathPermission[] pps = cpi.pathPermissions;
10506 int i = pps.length;
10509 PathPermission pp = pps[i];
10510 String pprperm = pp.getReadPermission();
10511 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10512 cpi.applicationInfo.uid, cpi.exported)
10513 == PackageManager.PERMISSION_GRANTED) {
10516 String ppwperm = pp.getWritePermission();
10517 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10518 cpi.applicationInfo.uid, cpi.exported)
10519 == PackageManager.PERMISSION_GRANTED) {
10524 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10529 if (!cpi.exported) {
10530 msg = "Permission Denial: opening provider " + cpi.name
10531 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10532 + ", uid=" + callingUid + ") that is not exported from uid "
10533 + cpi.applicationInfo.uid;
10535 msg = "Permission Denial: opening provider " + cpi.name
10536 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10537 + ", uid=" + callingUid + ") requires "
10538 + cpi.readPermission + " or " + cpi.writePermission;
10545 * Returns if the ContentProvider has granted a uri to callingUid
10547 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10548 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10549 if (perms != null) {
10550 for (int i=perms.size()-1; i>=0; i--) {
10551 GrantUri grantUri = perms.keyAt(i);
10552 if (grantUri.sourceUserId == userId || !checkUser) {
10553 if (matchesProvider(grantUri.uri, cpi)) {
10563 * Returns true if the uri authority is one of the authorities specified in the provider.
10565 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10566 String uriAuth = uri.getAuthority();
10567 String cpiAuth = cpi.authority;
10568 if (cpiAuth.indexOf(';') == -1) {
10569 return cpiAuth.equals(uriAuth);
10571 String[] cpiAuths = cpiAuth.split(";");
10572 int length = cpiAuths.length;
10573 for (int i = 0; i < length; i++) {
10574 if (cpiAuths[i].equals(uriAuth)) return true;
10579 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10580 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10582 for (int i=0; i<r.conProviders.size(); i++) {
10583 ContentProviderConnection conn = r.conProviders.get(i);
10584 if (conn.provider == cpr) {
10585 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10586 "Adding provider requested by "
10587 + r.processName + " from process "
10588 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10589 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10591 conn.stableCount++;
10592 conn.numStableIncs++;
10594 conn.unstableCount++;
10595 conn.numUnstableIncs++;
10600 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10602 conn.stableCount = 1;
10603 conn.numStableIncs = 1;
10605 conn.unstableCount = 1;
10606 conn.numUnstableIncs = 1;
10608 cpr.connections.add(conn);
10609 r.conProviders.add(conn);
10610 startAssociationLocked(r.uid, r.processName, r.curProcState,
10611 cpr.uid, cpr.name, cpr.info.processName);
10614 cpr.addExternalProcessHandleLocked(externalProcessToken);
10618 boolean decProviderCountLocked(ContentProviderConnection conn,
10619 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10620 if (conn != null) {
10621 cpr = conn.provider;
10622 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10623 "Removing provider requested by "
10624 + conn.client.processName + " from process "
10625 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10626 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10628 conn.stableCount--;
10630 conn.unstableCount--;
10632 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10633 cpr.connections.remove(conn);
10634 conn.client.conProviders.remove(conn);
10635 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10636 // The client is more important than last activity -- note the time this
10637 // is happening, so we keep the old provider process around a bit as last
10638 // activity to avoid thrashing it.
10639 if (cpr.proc != null) {
10640 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10643 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10648 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10652 private void checkTime(long startTime, String where) {
10653 long now = SystemClock.uptimeMillis();
10654 if ((now-startTime) > 50) {
10655 // If we are taking more than 50ms, log about it.
10656 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10660 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10662 PROC_SPACE_TERM|PROC_PARENS,
10663 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
10666 private final long[] mProcessStateStatsLongs = new long[1];
10668 boolean isProcessAliveLocked(ProcessRecord proc) {
10669 if (proc.procStatFile == null) {
10670 proc.procStatFile = "/proc/" + proc.pid + "/stat";
10672 mProcessStateStatsLongs[0] = 0;
10673 if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10674 mProcessStateStatsLongs, null)) {
10675 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10678 final long state = mProcessStateStatsLongs[0];
10679 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10681 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10684 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10685 String name, IBinder token, boolean stable, int userId) {
10686 ContentProviderRecord cpr;
10687 ContentProviderConnection conn = null;
10688 ProviderInfo cpi = null;
10690 synchronized(this) {
10691 long startTime = SystemClock.uptimeMillis();
10693 ProcessRecord r = null;
10694 if (caller != null) {
10695 r = getRecordForAppLocked(caller);
10697 throw new SecurityException(
10698 "Unable to find app for caller " + caller
10699 + " (pid=" + Binder.getCallingPid()
10700 + ") when getting content provider " + name);
10704 boolean checkCrossUser = true;
10706 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10708 // First check if this content provider has been published...
10709 cpr = mProviderMap.getProviderByName(name, userId);
10710 // If that didn't work, check if it exists for user 0 and then
10711 // verify that it's a singleton provider before using it.
10712 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10713 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10716 if (isSingleton(cpi.processName, cpi.applicationInfo,
10717 cpi.name, cpi.flags)
10718 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10719 userId = UserHandle.USER_SYSTEM;
10720 checkCrossUser = false;
10728 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10729 if (providerRunning) {
10732 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10733 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10735 throw new SecurityException(msg);
10737 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10739 if (r != null && cpr.canRunHere(r)) {
10740 // This provider has been published or is in the process
10741 // of being published... but it is also allowed to run
10742 // in the caller's process, so don't make a connection
10743 // and just let the caller instantiate its own instance.
10744 ContentProviderHolder holder = cpr.newHolder(null);
10745 // don't give caller the provider object, it needs
10746 // to make its own.
10747 holder.provider = null;
10751 final long origId = Binder.clearCallingIdentity();
10753 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10755 // In this case the provider instance already exists, so we can
10756 // return it right away.
10757 conn = incProviderCountLocked(r, cpr, token, stable);
10758 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10759 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10760 // If this is a perceptible app accessing the provider,
10761 // make sure to count it as being accessed and thus
10762 // back up on the LRU list. This is good because
10763 // content providers are often expensive to start.
10764 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10765 updateLruProcessLocked(cpr.proc, false, null);
10766 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10770 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10771 final int verifiedAdj = cpr.proc.verifiedAdj;
10772 boolean success = updateOomAdjLocked(cpr.proc);
10773 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10774 // if the process has been successfully adjusted. So to reduce races with
10775 // it, we will check whether the process still exists. Note that this doesn't
10776 // completely get rid of races with LMK killing the process, but should make
10777 // them much smaller.
10778 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10781 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10782 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10783 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10784 // NOTE: there is still a race here where a signal could be
10785 // pending on the process even though we managed to update its
10786 // adj level. Not sure what to do about this, but at least
10787 // the race is now smaller.
10789 // Uh oh... it looks like the provider's process
10790 // has been killed on us. We need to wait for a new
10791 // process to be started, and make sure its death
10792 // doesn't kill our process.
10793 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10794 + " is crashing; detaching " + r);
10795 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10796 checkTime(startTime, "getContentProviderImpl: before appDied");
10797 appDiedLocked(cpr.proc);
10798 checkTime(startTime, "getContentProviderImpl: after appDied");
10800 // This wasn't the last ref our process had on
10801 // the provider... we have now been killed, bail.
10804 providerRunning = false;
10807 cpr.proc.verifiedAdj = cpr.proc.setAdj;
10810 Binder.restoreCallingIdentity(origId);
10813 if (!providerRunning) {
10815 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10816 cpi = AppGlobals.getPackageManager().
10817 resolveContentProvider(name,
10818 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10819 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10820 } catch (RemoteException ex) {
10825 // If the provider is a singleton AND
10826 // (it's a call within the same user || the provider is a
10828 // Then allow connecting to the singleton provider
10829 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10830 cpi.name, cpi.flags)
10831 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10833 userId = UserHandle.USER_SYSTEM;
10835 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10836 checkTime(startTime, "getContentProviderImpl: got app info for user");
10839 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10840 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10842 throw new SecurityException(msg);
10844 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10846 if (!mProcessesReady
10847 && !cpi.processName.equals("system")) {
10848 // If this content provider does not run in the system
10849 // process, and the system is not yet ready to run other
10850 // processes, then fail fast instead of hanging.
10851 throw new IllegalArgumentException(
10852 "Attempt to launch content provider before system ready");
10855 // Make sure that the user who owns this provider is running. If not,
10856 // we don't want to allow it to run.
10857 if (!mUserController.isUserRunningLocked(userId, 0)) {
10858 Slog.w(TAG, "Unable to launch app "
10859 + cpi.applicationInfo.packageName + "/"
10860 + cpi.applicationInfo.uid + " for provider "
10861 + name + ": user " + userId + " is stopped");
10865 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10866 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10867 cpr = mProviderMap.getProviderByClass(comp, userId);
10868 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10869 final boolean firstClass = cpr == null;
10871 final long ident = Binder.clearCallingIdentity();
10873 // If permissions need a review before any of the app components can run,
10874 // we return no provider and launch a review activity if the calling app
10875 // is in the foreground.
10876 if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10877 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10883 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10884 ApplicationInfo ai =
10885 AppGlobals.getPackageManager().
10886 getApplicationInfo(
10887 cpi.applicationInfo.packageName,
10888 STOCK_PM_FLAGS, userId);
10889 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10891 Slog.w(TAG, "No package info for content provider "
10895 ai = getAppInfoForUser(ai, userId);
10896 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10897 } catch (RemoteException ex) {
10898 // pm is in same process, this will never happen.
10900 Binder.restoreCallingIdentity(ident);
10904 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10906 if (r != null && cpr.canRunHere(r)) {
10907 // If this is a multiprocess provider, then just return its
10908 // info and allow the caller to instantiate it. Only do
10909 // this if the provider is the same user as the caller's
10910 // process, or can run as root (so can be in any process).
10911 return cpr.newHolder(null);
10914 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10915 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10916 + cpr.info.name + " callers=" + Debug.getCallers(6));
10918 // This is single process, and our app is now connecting to it.
10919 // See if we are already in the process of launching this
10921 final int N = mLaunchingProviders.size();
10923 for (i = 0; i < N; i++) {
10924 if (mLaunchingProviders.get(i) == cpr) {
10929 // If the provider is not already being launched, then get it
10932 final long origId = Binder.clearCallingIdentity();
10935 // Content provider is now in use, its package can't be stopped.
10937 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10938 AppGlobals.getPackageManager().setPackageStoppedState(
10939 cpr.appInfo.packageName, false, userId);
10940 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10941 } catch (RemoteException e) {
10942 } catch (IllegalArgumentException e) {
10943 Slog.w(TAG, "Failed trying to unstop package "
10944 + cpr.appInfo.packageName + ": " + e);
10947 // Use existing process if already started
10948 checkTime(startTime, "getContentProviderImpl: looking for process record");
10949 ProcessRecord proc = getProcessRecordLocked(
10950 cpi.processName, cpr.appInfo.uid, false);
10951 if (proc != null && proc.thread != null && !proc.killed) {
10952 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10953 "Installing in existing process " + proc);
10954 if (!proc.pubProviders.containsKey(cpi.name)) {
10955 checkTime(startTime, "getContentProviderImpl: scheduling install");
10956 proc.pubProviders.put(cpi.name, cpr);
10958 proc.thread.scheduleInstallProvider(cpi);
10959 } catch (RemoteException e) {
10963 checkTime(startTime, "getContentProviderImpl: before start process");
10964 proc = startProcessLocked(cpi.processName,
10965 cpr.appInfo, false, 0, "content provider",
10966 new ComponentName(cpi.applicationInfo.packageName,
10967 cpi.name), false, false, false);
10968 checkTime(startTime, "getContentProviderImpl: after start process");
10969 if (proc == null) {
10970 Slog.w(TAG, "Unable to launch app "
10971 + cpi.applicationInfo.packageName + "/"
10972 + cpi.applicationInfo.uid + " for provider "
10973 + name + ": process is bad");
10977 cpr.launchingApp = proc;
10978 mLaunchingProviders.add(cpr);
10980 Binder.restoreCallingIdentity(origId);
10984 checkTime(startTime, "getContentProviderImpl: updating data structures");
10986 // Make sure the provider is published (the same provider class
10987 // may be published under multiple names).
10989 mProviderMap.putProviderByClass(comp, cpr);
10992 mProviderMap.putProviderByName(name, cpr);
10993 conn = incProviderCountLocked(r, cpr, token, stable);
10994 if (conn != null) {
10995 conn.waiting = true;
10998 checkTime(startTime, "getContentProviderImpl: done!");
11001 // Wait for the provider to be published...
11002 synchronized (cpr) {
11003 while (cpr.provider == null) {
11004 if (cpr.launchingApp == null) {
11005 Slog.w(TAG, "Unable to launch app "
11006 + cpi.applicationInfo.packageName + "/"
11007 + cpi.applicationInfo.uid + " for provider "
11008 + name + ": launching app became null");
11009 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11010 UserHandle.getUserId(cpi.applicationInfo.uid),
11011 cpi.applicationInfo.packageName,
11012 cpi.applicationInfo.uid, name);
11016 if (DEBUG_MU) Slog.v(TAG_MU,
11017 "Waiting to start provider " + cpr
11018 + " launchingApp=" + cpr.launchingApp);
11019 if (conn != null) {
11020 conn.waiting = true;
11023 } catch (InterruptedException ex) {
11025 if (conn != null) {
11026 conn.waiting = false;
11031 return cpr != null ? cpr.newHolder(conn) : null;
11034 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11035 ProcessRecord r, final int userId) {
11036 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11037 cpi.packageName, userId)) {
11039 final boolean callerForeground = r == null || r.setSchedGroup
11040 != ProcessList.SCHED_GROUP_BACKGROUND;
11042 // Show a permission review UI only for starting from a foreground app
11043 if (!callerForeground) {
11044 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11045 + cpi.packageName + " requires a permissions review");
11049 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11050 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11051 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11052 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11054 if (DEBUG_PERMISSIONS_REVIEW) {
11055 Slog.i(TAG, "u" + userId + " Launching permission review "
11056 + "for package " + cpi.packageName);
11059 final UserHandle userHandle = new UserHandle(userId);
11060 mHandler.post(new Runnable() {
11062 public void run() {
11063 mContext.startActivityAsUser(intent, userHandle);
11073 PackageManagerInternal getPackageManagerInternalLocked() {
11074 if (mPackageManagerInt == null) {
11075 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11077 return mPackageManagerInt;
11081 public final ContentProviderHolder getContentProvider(
11082 IApplicationThread caller, String name, int userId, boolean stable) {
11083 enforceNotIsolatedCaller("getContentProvider");
11084 if (caller == null) {
11085 String msg = "null IApplicationThread when getting content provider "
11088 throw new SecurityException(msg);
11090 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11091 // with cross-user grant.
11092 return getContentProviderImpl(caller, name, null, stable, userId);
11095 public ContentProviderHolder getContentProviderExternal(
11096 String name, int userId, IBinder token) {
11097 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11098 "Do not have permission in call getContentProviderExternal()");
11099 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11100 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11101 return getContentProviderExternalUnchecked(name, token, userId);
11104 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11105 IBinder token, int userId) {
11106 return getContentProviderImpl(null, name, token, true, userId);
11110 * Drop a content provider from a ProcessRecord's bookkeeping
11112 public void removeContentProvider(IBinder connection, boolean stable) {
11113 enforceNotIsolatedCaller("removeContentProvider");
11114 long ident = Binder.clearCallingIdentity();
11116 synchronized (this) {
11117 ContentProviderConnection conn;
11119 conn = (ContentProviderConnection)connection;
11120 } catch (ClassCastException e) {
11121 String msg ="removeContentProvider: " + connection
11122 + " not a ContentProviderConnection";
11124 throw new IllegalArgumentException(msg);
11126 if (conn == null) {
11127 throw new NullPointerException("connection is null");
11129 if (decProviderCountLocked(conn, null, null, stable)) {
11130 updateOomAdjLocked();
11134 Binder.restoreCallingIdentity(ident);
11138 public void removeContentProviderExternal(String name, IBinder token) {
11139 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11140 "Do not have permission in call removeContentProviderExternal()");
11141 int userId = UserHandle.getCallingUserId();
11142 long ident = Binder.clearCallingIdentity();
11144 removeContentProviderExternalUnchecked(name, token, userId);
11146 Binder.restoreCallingIdentity(ident);
11150 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11151 synchronized (this) {
11152 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11154 //remove from mProvidersByClass
11155 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11159 //update content provider record entry info
11160 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11161 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11162 if (localCpr.hasExternalProcessHandles()) {
11163 if (localCpr.removeExternalProcessHandleLocked(token)) {
11164 updateOomAdjLocked();
11166 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11167 + " with no external reference for token: "
11171 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11172 + " with no external references.");
11177 public final void publishContentProviders(IApplicationThread caller,
11178 List<ContentProviderHolder> providers) {
11179 if (providers == null) {
11183 enforceNotIsolatedCaller("publishContentProviders");
11184 synchronized (this) {
11185 final ProcessRecord r = getRecordForAppLocked(caller);
11186 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11188 throw new SecurityException(
11189 "Unable to find app for caller " + caller
11190 + " (pid=" + Binder.getCallingPid()
11191 + ") when publishing content providers");
11194 final long origId = Binder.clearCallingIdentity();
11196 final int N = providers.size();
11197 for (int i = 0; i < N; i++) {
11198 ContentProviderHolder src = providers.get(i);
11199 if (src == null || src.info == null || src.provider == null) {
11202 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11203 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11205 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11206 mProviderMap.putProviderByClass(comp, dst);
11207 String names[] = dst.info.authority.split(";");
11208 for (int j = 0; j < names.length; j++) {
11209 mProviderMap.putProviderByName(names[j], dst);
11212 int launchingCount = mLaunchingProviders.size();
11214 boolean wasInLaunchingProviders = false;
11215 for (j = 0; j < launchingCount; j++) {
11216 if (mLaunchingProviders.get(j) == dst) {
11217 mLaunchingProviders.remove(j);
11218 wasInLaunchingProviders = true;
11223 if (wasInLaunchingProviders) {
11224 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11226 synchronized (dst) {
11227 dst.provider = src.provider;
11231 updateOomAdjLocked(r);
11232 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11233 src.info.authority);
11237 Binder.restoreCallingIdentity(origId);
11241 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11242 ContentProviderConnection conn;
11244 conn = (ContentProviderConnection)connection;
11245 } catch (ClassCastException e) {
11246 String msg ="refContentProvider: " + connection
11247 + " not a ContentProviderConnection";
11249 throw new IllegalArgumentException(msg);
11251 if (conn == null) {
11252 throw new NullPointerException("connection is null");
11255 synchronized (this) {
11257 conn.numStableIncs += stable;
11259 stable = conn.stableCount + stable;
11261 throw new IllegalStateException("stableCount < 0: " + stable);
11264 if (unstable > 0) {
11265 conn.numUnstableIncs += unstable;
11267 unstable = conn.unstableCount + unstable;
11268 if (unstable < 0) {
11269 throw new IllegalStateException("unstableCount < 0: " + unstable);
11272 if ((stable+unstable) <= 0) {
11273 throw new IllegalStateException("ref counts can't go to zero here: stable="
11274 + stable + " unstable=" + unstable);
11276 conn.stableCount = stable;
11277 conn.unstableCount = unstable;
11282 public void unstableProviderDied(IBinder connection) {
11283 ContentProviderConnection conn;
11285 conn = (ContentProviderConnection)connection;
11286 } catch (ClassCastException e) {
11287 String msg ="refContentProvider: " + connection
11288 + " not a ContentProviderConnection";
11290 throw new IllegalArgumentException(msg);
11292 if (conn == null) {
11293 throw new NullPointerException("connection is null");
11296 // Safely retrieve the content provider associated with the connection.
11297 IContentProvider provider;
11298 synchronized (this) {
11299 provider = conn.provider.provider;
11302 if (provider == null) {
11303 // Um, yeah, we're way ahead of you.
11307 // Make sure the caller is being honest with us.
11308 if (provider.asBinder().pingBinder()) {
11309 // Er, no, still looks good to us.
11310 synchronized (this) {
11311 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11312 + " says " + conn + " died, but we don't agree");
11317 // Well look at that! It's dead!
11318 synchronized (this) {
11319 if (conn.provider.provider != provider) {
11320 // But something changed... good enough.
11324 ProcessRecord proc = conn.provider.proc;
11325 if (proc == null || proc.thread == null) {
11326 // Seems like the process is already cleaned up.
11330 // As far as we're concerned, this is just like receiving a
11331 // death notification... just a bit prematurely.
11332 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11333 + ") early provider death");
11334 final long ident = Binder.clearCallingIdentity();
11336 appDiedLocked(proc);
11338 Binder.restoreCallingIdentity(ident);
11344 public void appNotRespondingViaProvider(IBinder connection) {
11345 enforceCallingPermission(
11346 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11348 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11349 if (conn == null) {
11350 Slog.w(TAG, "ContentProviderConnection is null");
11354 final ProcessRecord host = conn.provider.proc;
11355 if (host == null) {
11356 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11360 mHandler.post(new Runnable() {
11362 public void run() {
11363 mAppErrors.appNotResponding(host, null, null, false,
11364 "ContentProvider not responding");
11369 public final void installSystemProviders() {
11370 List<ProviderInfo> providers;
11371 synchronized (this) {
11372 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11373 providers = generateApplicationProvidersLocked(app);
11374 if (providers != null) {
11375 for (int i=providers.size()-1; i>=0; i--) {
11376 ProviderInfo pi = (ProviderInfo)providers.get(i);
11377 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11378 Slog.w(TAG, "Not installing system proc provider " + pi.name
11379 + ": not system .apk");
11380 providers.remove(i);
11385 if (providers != null) {
11386 mSystemThread.installSystemProviders(providers);
11389 mCoreSettingsObserver = new CoreSettingsObserver(this);
11390 mFontScaleSettingObserver = new FontScaleSettingObserver();
11392 //mUsageStatsService.monitorPackages();
11395 private void startPersistentApps(int matchFlags) {
11396 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11398 synchronized (this) {
11400 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11401 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11402 for (ApplicationInfo app : apps) {
11403 if (!"android".equals(app.packageName)) {
11404 addAppLocked(app, false, null /* ABI override */);
11407 } catch (RemoteException ex) {
11413 * When a user is unlocked, we need to install encryption-unaware providers
11414 * belonging to any running apps.
11416 private void installEncryptionUnawareProviders(int userId) {
11417 // We're only interested in providers that are encryption unaware, and
11418 // we don't care about uninstalled apps, since there's no way they're
11419 // running at this point.
11420 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11422 synchronized (this) {
11423 final int NP = mProcessNames.getMap().size();
11424 for (int ip = 0; ip < NP; ip++) {
11425 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11426 final int NA = apps.size();
11427 for (int ia = 0; ia < NA; ia++) {
11428 final ProcessRecord app = apps.valueAt(ia);
11429 if (app.userId != userId || app.thread == null || app.unlocked) continue;
11431 final int NG = app.pkgList.size();
11432 for (int ig = 0; ig < NG; ig++) {
11434 final String pkgName = app.pkgList.keyAt(ig);
11435 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11436 .getPackageInfo(pkgName, matchFlags, userId);
11437 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11438 for (ProviderInfo pi : pkgInfo.providers) {
11439 // TODO: keep in sync with generateApplicationProvidersLocked
11440 final boolean processMatch = Objects.equals(pi.processName,
11441 app.processName) || pi.multiprocess;
11442 final boolean userMatch = isSingleton(pi.processName,
11443 pi.applicationInfo, pi.name, pi.flags)
11444 ? (app.userId == UserHandle.USER_SYSTEM) : true;
11445 if (processMatch && userMatch) {
11446 Log.v(TAG, "Installing " + pi);
11447 app.thread.scheduleInstallProvider(pi);
11449 Log.v(TAG, "Skipping " + pi);
11453 } catch (RemoteException ignored) {
11462 * Allows apps to retrieve the MIME type of a URI.
11463 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11464 * users, then it does not need permission to access the ContentProvider.
11465 * Either, it needs cross-user uri grants.
11467 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11469 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11470 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11472 public String getProviderMimeType(Uri uri, int userId) {
11473 enforceNotIsolatedCaller("getProviderMimeType");
11474 final String name = uri.getAuthority();
11475 int callingUid = Binder.getCallingUid();
11476 int callingPid = Binder.getCallingPid();
11478 boolean clearedIdentity = false;
11479 synchronized (this) {
11480 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11482 if (canClearIdentity(callingPid, callingUid, userId)) {
11483 clearedIdentity = true;
11484 ident = Binder.clearCallingIdentity();
11486 ContentProviderHolder holder = null;
11488 holder = getContentProviderExternalUnchecked(name, null, userId);
11489 if (holder != null) {
11490 return holder.provider.getType(uri);
11492 } catch (RemoteException e) {
11493 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11495 } catch (Exception e) {
11496 Log.w(TAG, "Exception while determining type of " + uri, e);
11499 // We need to clear the identity to call removeContentProviderExternalUnchecked
11500 if (!clearedIdentity) {
11501 ident = Binder.clearCallingIdentity();
11504 if (holder != null) {
11505 removeContentProviderExternalUnchecked(name, null, userId);
11508 Binder.restoreCallingIdentity(ident);
11515 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11516 if (UserHandle.getUserId(callingUid) == userId) {
11519 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11520 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11521 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11522 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11528 // =========================================================
11529 // GLOBAL MANAGEMENT
11530 // =========================================================
11532 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11533 boolean isolated, int isolatedUid) {
11534 String proc = customProcess != null ? customProcess : info.processName;
11535 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11536 final int userId = UserHandle.getUserId(info.uid);
11537 int uid = info.uid;
11539 if (isolatedUid == 0) {
11540 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11542 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11543 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11544 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11546 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11547 mNextIsolatedProcessUid++;
11548 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11549 // No process for this uid, use it.
11553 if (stepsLeft <= 0) {
11558 // Special case for startIsolatedProcess (internal only), where
11559 // the uid of the isolated process is specified by the caller.
11563 // Register the isolated UID with this application so BatteryStats knows to
11564 // attribute resource usage to the application.
11566 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11567 // about the process state of the isolated UID *before* it is registered with the
11568 // owning application.
11569 mBatteryStatsService.addIsolatedUid(uid, info.uid);
11571 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11572 if (!mBooted && !mBooting
11573 && userId == UserHandle.USER_SYSTEM
11574 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11575 r.persistent = true;
11577 addProcessNameLocked(r);
11581 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11582 String abiOverride) {
11585 app = getProcessRecordLocked(info.processName, info.uid, true);
11591 app = newProcessRecordLocked(info, null, isolated, 0);
11592 updateLruProcessLocked(app, false, null);
11593 updateOomAdjLocked();
11596 // This package really, really can not be stopped.
11598 AppGlobals.getPackageManager().setPackageStoppedState(
11599 info.packageName, false, UserHandle.getUserId(app.uid));
11600 } catch (RemoteException e) {
11601 } catch (IllegalArgumentException e) {
11602 Slog.w(TAG, "Failed trying to unstop package "
11603 + info.packageName + ": " + e);
11606 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11607 app.persistent = true;
11608 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11610 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11611 mPersistentStartingProcesses.add(app);
11612 startProcessLocked(app, "added application", app.processName, abiOverride,
11613 null /* entryPoint */, null /* entryPointArgs */);
11619 public void unhandledBack() {
11620 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11621 "unhandledBack()");
11623 synchronized(this) {
11624 final long origId = Binder.clearCallingIdentity();
11626 getFocusedStack().unhandledBackLocked();
11628 Binder.restoreCallingIdentity(origId);
11633 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11634 enforceNotIsolatedCaller("openContentUri");
11635 final int userId = UserHandle.getCallingUserId();
11636 String name = uri.getAuthority();
11637 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11638 ParcelFileDescriptor pfd = null;
11640 // We record the binder invoker's uid in thread-local storage before
11641 // going to the content provider to open the file. Later, in the code
11642 // that handles all permissions checks, we look for this uid and use
11643 // that rather than the Activity Manager's own uid. The effect is that
11644 // we do the check against the caller's permissions even though it looks
11645 // to the content provider like the Activity Manager itself is making
11647 Binder token = new Binder();
11648 sCallerIdentity.set(new Identity(
11649 token, Binder.getCallingPid(), Binder.getCallingUid()));
11651 pfd = cph.provider.openFile(null, uri, "r", null, token);
11652 } catch (FileNotFoundException e) {
11653 // do nothing; pfd will be returned null
11655 // Ensure that whatever happens, we clean up the identity state
11656 sCallerIdentity.remove();
11657 // Ensure we're done with the provider.
11658 removeContentProviderExternalUnchecked(name, null, userId);
11661 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11666 // Actually is sleeping or shutting down or whatever else in the future
11667 // is an inactive state.
11668 boolean isSleepingOrShuttingDownLocked() {
11669 return isSleepingLocked() || mShuttingDown;
11672 boolean isShuttingDownLocked() {
11673 return mShuttingDown;
11676 boolean isSleepingLocked() {
11680 void onWakefulnessChanged(int wakefulness) {
11681 synchronized(this) {
11682 mWakefulness = wakefulness;
11683 updateSleepIfNeededLocked();
11687 void finishRunningVoiceLocked() {
11688 if (mRunningVoice != null) {
11689 mRunningVoice = null;
11690 mVoiceWakeLock.release();
11691 updateSleepIfNeededLocked();
11695 void startTimeTrackingFocusedActivityLocked() {
11696 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11697 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11701 void updateSleepIfNeededLocked() {
11702 if (mSleeping && !shouldSleepLocked()) {
11704 startTimeTrackingFocusedActivityLocked();
11705 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11706 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11707 updateOomAdjLocked();
11708 } else if (!mSleeping && shouldSleepLocked()) {
11710 if (mCurAppTimeTracker != null) {
11711 mCurAppTimeTracker.stop();
11713 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11714 mStackSupervisor.goingToSleepLocked();
11715 updateOomAdjLocked();
11717 // Initialize the wake times of all processes.
11718 checkExcessivePowerUsageLocked(false);
11719 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11720 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11721 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11725 private boolean shouldSleepLocked() {
11726 // Resume applications while running a voice interactor.
11727 if (mRunningVoice != null) {
11731 // TODO: Transform the lock screen state into a sleep token instead.
11732 switch (mWakefulness) {
11733 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11734 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11735 case PowerManagerInternal.WAKEFULNESS_DOZING:
11736 // Pause applications whenever the lock screen is shown or any sleep
11737 // tokens have been acquired.
11738 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11739 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11741 // If we're asleep then pause applications unconditionally.
11746 /** Pokes the task persister. */
11747 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11748 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11751 /** Notifies all listeners when the task stack has changed. */
11752 void notifyTaskStackChangedLocked() {
11753 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11754 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11755 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11756 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11759 /** Notifies all listeners when an Activity is pinned. */
11760 void notifyActivityPinnedLocked() {
11761 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11762 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11766 * Notifies all listeners when an attempt was made to start an an activity that is already
11767 * running in the pinned stack and the activity was not actually started, but the task is
11768 * either brought to the front or a new Intent is delivered to it.
11770 void notifyPinnedActivityRestartAttemptLocked() {
11771 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11772 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11775 /** Notifies all listeners when the pinned stack animation ends. */
11777 public void notifyPinnedStackAnimationEnded() {
11778 synchronized (this) {
11779 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11780 mHandler.obtainMessage(
11781 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11786 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11787 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11791 public boolean shutdown(int timeout) {
11792 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11793 != PackageManager.PERMISSION_GRANTED) {
11794 throw new SecurityException("Requires permission "
11795 + android.Manifest.permission.SHUTDOWN);
11798 boolean timedout = false;
11800 synchronized(this) {
11801 mShuttingDown = true;
11802 updateEventDispatchingLocked();
11803 timedout = mStackSupervisor.shutdownLocked(timeout);
11806 mAppOpsService.shutdown();
11807 if (mUsageStatsService != null) {
11808 mUsageStatsService.prepareShutdown();
11810 mBatteryStatsService.shutdown();
11811 synchronized (this) {
11812 mProcessStats.shutdownLocked();
11813 notifyTaskPersisterLocked(null, true);
11819 public final void activitySlept(IBinder token) {
11820 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11822 final long origId = Binder.clearCallingIdentity();
11824 synchronized (this) {
11825 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11827 mStackSupervisor.activitySleptLocked(r);
11831 Binder.restoreCallingIdentity(origId);
11834 private String lockScreenShownToString() {
11835 switch (mLockScreenShown) {
11836 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11837 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11838 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11839 default: return "Unknown=" + mLockScreenShown;
11843 void logLockScreen(String msg) {
11844 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11845 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11846 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11847 + " mSleeping=" + mSleeping);
11850 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11851 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11852 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11853 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11854 boolean wasRunningVoice = mRunningVoice != null;
11855 mRunningVoice = session;
11856 if (!wasRunningVoice) {
11857 mVoiceWakeLock.acquire();
11858 updateSleepIfNeededLocked();
11863 private void updateEventDispatchingLocked() {
11864 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11867 public void setLockScreenShown(boolean showing, boolean occluded) {
11868 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11869 != PackageManager.PERMISSION_GRANTED) {
11870 throw new SecurityException("Requires permission "
11871 + android.Manifest.permission.DEVICE_POWER);
11874 synchronized(this) {
11875 long ident = Binder.clearCallingIdentity();
11877 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11878 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11879 if (showing && occluded) {
11880 // The lock screen is currently showing, but is occluded by a window that can
11881 // show on top of the lock screen. In this can we want to dismiss the docked
11882 // stack since it will be complicated/risky to try to put the activity on top
11883 // of the lock screen in the right fullscreen configuration.
11884 mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11885 mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11888 updateSleepIfNeededLocked();
11890 Binder.restoreCallingIdentity(ident);
11896 public void notifyLockedProfile(@UserIdInt int userId) {
11898 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11899 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11901 } catch (RemoteException ex) {
11902 throw new SecurityException("Fail to check is caller a privileged app", ex);
11905 synchronized (this) {
11906 if (mStackSupervisor.isUserLockedProfile(userId)) {
11907 final long ident = Binder.clearCallingIdentity();
11909 final int currentUserId = mUserController.getCurrentUserIdLocked();
11911 // Drop locked freeform tasks out into the fullscreen stack.
11912 // TODO: Redact the tasks in place. It's much better to keep them on the screen
11913 // where they were before, but in an obscured state.
11914 mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11916 if (mUserController.isLockScreenDisabled(currentUserId)) {
11917 // If there is no device lock, we will show the profile's credential page.
11918 mActivityStarter.showConfirmDeviceCredential(userId);
11920 // Showing launcher to avoid user entering credential twice.
11921 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11924 Binder.restoreCallingIdentity(ident);
11931 public void startConfirmDeviceCredentialIntent(Intent intent) {
11932 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11933 synchronized (this) {
11934 final long ident = Binder.clearCallingIdentity();
11936 mActivityStarter.startConfirmCredentialIntent(intent);
11938 Binder.restoreCallingIdentity(ident);
11944 public void stopAppSwitches() {
11945 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11946 != PackageManager.PERMISSION_GRANTED) {
11947 throw new SecurityException("viewquires permission "
11948 + android.Manifest.permission.STOP_APP_SWITCHES);
11951 synchronized(this) {
11952 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11953 + APP_SWITCH_DELAY_TIME;
11954 mDidAppSwitch = false;
11955 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11956 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11957 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11961 public void resumeAppSwitches() {
11962 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11963 != PackageManager.PERMISSION_GRANTED) {
11964 throw new SecurityException("Requires permission "
11965 + android.Manifest.permission.STOP_APP_SWITCHES);
11968 synchronized(this) {
11969 // Note that we don't execute any pending app switches... we will
11970 // let those wait until either the timeout, or the next start
11971 // activity request.
11972 mAppSwitchesAllowedTime = 0;
11976 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11977 int callingPid, int callingUid, String name) {
11978 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11982 int perm = checkComponentPermission(
11983 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11984 sourceUid, -1, true);
11985 if (perm == PackageManager.PERMISSION_GRANTED) {
11989 // If the actual IPC caller is different from the logical source, then
11990 // also see if they are allowed to control app switches.
11991 if (callingUid != -1 && callingUid != sourceUid) {
11992 perm = checkComponentPermission(
11993 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11994 callingUid, -1, true);
11995 if (perm == PackageManager.PERMISSION_GRANTED) {
12000 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12004 public void setDebugApp(String packageName, boolean waitForDebugger,
12005 boolean persistent) {
12006 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12009 long ident = Binder.clearCallingIdentity();
12011 // Note that this is not really thread safe if there are multiple
12012 // callers into it at the same time, but that's not a situation we
12015 final ContentResolver resolver = mContext.getContentResolver();
12016 Settings.Global.putString(
12017 resolver, Settings.Global.DEBUG_APP,
12019 Settings.Global.putInt(
12020 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12021 waitForDebugger ? 1 : 0);
12024 synchronized (this) {
12026 mOrigDebugApp = mDebugApp;
12027 mOrigWaitForDebugger = mWaitForDebugger;
12029 mDebugApp = packageName;
12030 mWaitForDebugger = waitForDebugger;
12031 mDebugTransient = !persistent;
12032 if (packageName != null) {
12033 forceStopPackageLocked(packageName, -1, false, false, true, true,
12034 false, UserHandle.USER_ALL, "set debug app");
12038 Binder.restoreCallingIdentity(ident);
12042 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12043 synchronized (this) {
12044 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12045 if (!isDebuggable) {
12046 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12047 throw new SecurityException("Process not debuggable: " + app.packageName);
12051 mTrackAllocationApp = processName;
12055 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12056 synchronized (this) {
12057 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12058 if (!isDebuggable) {
12059 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12060 throw new SecurityException("Process not debuggable: " + app.packageName);
12063 mProfileApp = processName;
12064 mProfileFile = profilerInfo.profileFile;
12065 if (mProfileFd != null) {
12067 mProfileFd.close();
12068 } catch (IOException e) {
12072 mProfileFd = profilerInfo.profileFd;
12073 mSamplingInterval = profilerInfo.samplingInterval;
12074 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12079 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12080 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12081 if (!isDebuggable) {
12082 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12083 throw new SecurityException("Process not debuggable: " + app.packageName);
12086 mNativeDebuggingApp = processName;
12090 public void setAlwaysFinish(boolean enabled) {
12091 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12092 "setAlwaysFinish()");
12094 long ident = Binder.clearCallingIdentity();
12096 Settings.Global.putInt(
12097 mContext.getContentResolver(),
12098 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12100 synchronized (this) {
12101 mAlwaysFinishActivities = enabled;
12104 Binder.restoreCallingIdentity(ident);
12109 public void setLenientBackgroundCheck(boolean enabled) {
12110 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12111 "setLenientBackgroundCheck()");
12113 long ident = Binder.clearCallingIdentity();
12115 Settings.Global.putInt(
12116 mContext.getContentResolver(),
12117 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12119 synchronized (this) {
12120 mLenientBackgroundCheck = enabled;
12123 Binder.restoreCallingIdentity(ident);
12128 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12129 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12130 "setActivityController()");
12131 synchronized (this) {
12132 mController = controller;
12133 mControllerIsAMonkey = imAMonkey;
12134 Watchdog.getInstance().setActivityController(controller);
12139 public void setUserIsMonkey(boolean userIsMonkey) {
12140 synchronized (this) {
12141 synchronized (mPidsSelfLocked) {
12142 final int callingPid = Binder.getCallingPid();
12143 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12144 if (precessRecord == null) {
12145 throw new SecurityException("Unknown process: " + callingPid);
12147 if (precessRecord.instrumentationUiAutomationConnection == null) {
12148 throw new SecurityException("Only an instrumentation process "
12149 + "with a UiAutomation can call setUserIsMonkey");
12152 mUserIsMonkey = userIsMonkey;
12157 public boolean isUserAMonkey() {
12158 synchronized (this) {
12159 // If there is a controller also implies the user is a monkey.
12160 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12164 public void requestBugReport(int bugreportType) {
12165 String service = null;
12166 switch (bugreportType) {
12167 case ActivityManager.BUGREPORT_OPTION_FULL:
12168 service = "bugreport";
12170 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12171 service = "bugreportplus";
12173 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12174 service = "bugreportremote";
12176 case ActivityManager.BUGREPORT_OPTION_WEAR:
12177 service = "bugreportwear";
12180 if (service == null) {
12181 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12184 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12185 SystemProperties.set("ctl.start", service);
12188 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12189 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12192 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12193 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12194 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12196 return KEY_DISPATCHING_TIMEOUT;
12200 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12201 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12202 != PackageManager.PERMISSION_GRANTED) {
12203 throw new SecurityException("Requires permission "
12204 + android.Manifest.permission.FILTER_EVENTS);
12206 ProcessRecord proc;
12208 synchronized (this) {
12209 synchronized (mPidsSelfLocked) {
12210 proc = mPidsSelfLocked.get(pid);
12212 timeout = getInputDispatchingTimeoutLocked(proc);
12215 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12223 * Handle input dispatching timeouts.
12224 * Returns whether input dispatching should be aborted or not.
12226 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12227 final ActivityRecord activity, final ActivityRecord parent,
12228 final boolean aboveSystem, String reason) {
12229 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12230 != PackageManager.PERMISSION_GRANTED) {
12231 throw new SecurityException("Requires permission "
12232 + android.Manifest.permission.FILTER_EVENTS);
12235 final String annotation;
12236 if (reason == null) {
12237 annotation = "Input dispatching timed out";
12239 annotation = "Input dispatching timed out (" + reason + ")";
12242 if (proc != null) {
12243 synchronized (this) {
12244 if (proc.debugging) {
12249 // Give more time since we were dexopting.
12250 mDidDexOpt = false;
12254 if (proc.instrumentationClass != null) {
12255 Bundle info = new Bundle();
12256 info.putString("shortMsg", "keyDispatchingTimedOut");
12257 info.putString("longMsg", annotation);
12258 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12262 mHandler.post(new Runnable() {
12264 public void run() {
12265 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12274 public Bundle getAssistContextExtras(int requestType) {
12275 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12276 null, null, true /* focused */, true /* newSessionId */,
12277 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12281 synchronized (pae) {
12282 while (!pae.haveResult) {
12285 } catch (InterruptedException e) {
12289 synchronized (this) {
12290 buildAssistBundleLocked(pae, pae.result);
12291 mPendingAssistExtras.remove(pae);
12292 mUiHandler.removeCallbacks(pae);
12298 public boolean isAssistDataAllowedOnCurrentActivity() {
12300 synchronized (this) {
12301 userId = mUserController.getCurrentUserIdLocked();
12302 ActivityRecord activity = getFocusedStack().topActivity();
12303 if (activity == null) {
12306 userId = activity.userId;
12308 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12309 Context.DEVICE_POLICY_SERVICE);
12310 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12314 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12315 long ident = Binder.clearCallingIdentity();
12317 synchronized (this) {
12318 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12319 ActivityRecord top = getFocusedStack().topActivity();
12320 if (top != caller) {
12321 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12322 + " is not current top " + top);
12325 if (!top.nowVisible) {
12326 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12327 + " is not visible");
12331 AssistUtils utils = new AssistUtils(mContext);
12332 return utils.showSessionForActiveService(args,
12333 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12335 Binder.restoreCallingIdentity(ident);
12340 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12341 Bundle receiverExtras,
12342 IBinder activityToken, boolean focused, boolean newSessionId) {
12343 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12344 activityToken, focused, newSessionId,
12345 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12349 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12350 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12351 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12352 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12353 "enqueueAssistContext()");
12354 synchronized (this) {
12355 ActivityRecord activity = getFocusedStack().topActivity();
12356 if (activity == null) {
12357 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12360 if (activity.app == null || activity.app.thread == null) {
12361 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12365 if (activityToken != null) {
12366 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12367 if (activity != caller) {
12368 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12369 + " is not current top " + activity);
12374 activity = ActivityRecord.forTokenLocked(activityToken);
12375 if (activity == null) {
12376 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12377 + " couldn't be found");
12382 PendingAssistExtras pae;
12383 Bundle extras = new Bundle();
12384 if (args != null) {
12385 extras.putAll(args);
12387 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12388 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12389 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12391 // Increment the sessionId if necessary
12392 if (newSessionId) {
12396 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12397 requestType, mViSessionId);
12398 mPendingAssistExtras.add(pae);
12399 mUiHandler.postDelayed(pae, timeout);
12400 } catch (RemoteException e) {
12401 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12408 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12409 IResultReceiver receiver;
12410 synchronized (this) {
12411 mPendingAssistExtras.remove(pae);
12412 receiver = pae.receiver;
12414 if (receiver != null) {
12415 // Caller wants result sent back to them.
12416 Bundle sendBundle = new Bundle();
12417 // At least return the receiver extras
12418 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12419 pae.receiverExtras);
12421 pae.receiver.send(0, sendBundle);
12422 } catch (RemoteException e) {
12427 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12428 if (result != null) {
12429 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12431 if (pae.hint != null) {
12432 pae.extras.putBoolean(pae.hint, true);
12436 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12437 AssistContent content, Uri referrer) {
12438 PendingAssistExtras pae = (PendingAssistExtras)token;
12439 synchronized (pae) {
12440 pae.result = extras;
12441 pae.structure = structure;
12442 pae.content = content;
12443 if (referrer != null) {
12444 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12446 pae.haveResult = true;
12448 if (pae.intent == null && pae.receiver == null) {
12449 // Caller is just waiting for the result.
12454 // We are now ready to launch the assist activity.
12455 IResultReceiver sendReceiver = null;
12456 Bundle sendBundle = null;
12457 synchronized (this) {
12458 buildAssistBundleLocked(pae, extras);
12459 boolean exists = mPendingAssistExtras.remove(pae);
12460 mUiHandler.removeCallbacks(pae);
12465 if ((sendReceiver=pae.receiver) != null) {
12466 // Caller wants result sent back to them.
12467 sendBundle = new Bundle();
12468 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12469 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12470 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12471 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12472 pae.receiverExtras);
12475 if (sendReceiver != null) {
12477 sendReceiver.send(0, sendBundle);
12478 } catch (RemoteException e) {
12483 long ident = Binder.clearCallingIdentity();
12485 pae.intent.replaceExtras(pae.extras);
12486 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12487 | Intent.FLAG_ACTIVITY_SINGLE_TOP
12488 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12489 closeSystemDialogs("assist");
12491 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12492 } catch (ActivityNotFoundException e) {
12493 Slog.w(TAG, "No activity to handle assist action.", e);
12496 Binder.restoreCallingIdentity(ident);
12500 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12502 return enqueueAssistContext(requestType, intent, hint, null, null, null,
12503 true /* focused */, true /* newSessionId */,
12504 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12507 public void registerProcessObserver(IProcessObserver observer) {
12508 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12509 "registerProcessObserver()");
12510 synchronized (this) {
12511 mProcessObservers.register(observer);
12516 public void unregisterProcessObserver(IProcessObserver observer) {
12517 synchronized (this) {
12518 mProcessObservers.unregister(observer);
12523 public void registerUidObserver(IUidObserver observer, int which) {
12524 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12525 "registerUidObserver()");
12526 synchronized (this) {
12527 mUidObservers.register(observer, which);
12532 public void unregisterUidObserver(IUidObserver observer) {
12533 synchronized (this) {
12534 mUidObservers.unregister(observer);
12539 public boolean convertFromTranslucent(IBinder token) {
12540 final long origId = Binder.clearCallingIdentity();
12542 synchronized (this) {
12543 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12547 final boolean translucentChanged = r.changeWindowTranslucency(true);
12548 if (translucentChanged) {
12549 r.task.stack.releaseBackgroundResources(r);
12550 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12552 mWindowManager.setAppFullscreen(token, true);
12553 return translucentChanged;
12556 Binder.restoreCallingIdentity(origId);
12561 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12562 final long origId = Binder.clearCallingIdentity();
12564 synchronized (this) {
12565 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12569 int index = r.task.mActivities.lastIndexOf(r);
12571 ActivityRecord under = r.task.mActivities.get(index - 1);
12572 under.returningOptions = options;
12574 final boolean translucentChanged = r.changeWindowTranslucency(false);
12575 if (translucentChanged) {
12576 r.task.stack.convertActivityToTranslucent(r);
12578 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12579 mWindowManager.setAppFullscreen(token, false);
12580 return translucentChanged;
12583 Binder.restoreCallingIdentity(origId);
12588 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12589 final long origId = Binder.clearCallingIdentity();
12591 synchronized (this) {
12592 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12594 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12599 Binder.restoreCallingIdentity(origId);
12604 public boolean isBackgroundVisibleBehind(IBinder token) {
12605 final long origId = Binder.clearCallingIdentity();
12607 synchronized (this) {
12608 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12609 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12610 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12611 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12615 Binder.restoreCallingIdentity(origId);
12620 public ActivityOptions getActivityOptions(IBinder token) {
12621 final long origId = Binder.clearCallingIdentity();
12623 synchronized (this) {
12624 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12626 final ActivityOptions activityOptions = r.pendingOptions;
12627 r.pendingOptions = null;
12628 return activityOptions;
12633 Binder.restoreCallingIdentity(origId);
12638 public void setImmersive(IBinder token, boolean immersive) {
12639 synchronized(this) {
12640 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12642 throw new IllegalArgumentException();
12644 r.immersive = immersive;
12646 // update associated state if we're frontmost
12647 if (r == mFocusedActivity) {
12648 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12649 applyUpdateLockStateLocked(r);
12655 public boolean isImmersive(IBinder token) {
12656 synchronized (this) {
12657 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12659 throw new IllegalArgumentException();
12661 return r.immersive;
12665 public void setVrThread(int tid) {
12666 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12667 throw new UnsupportedOperationException("VR mode not supported on this device!");
12670 synchronized (this) {
12671 ProcessRecord proc;
12672 synchronized (mPidsSelfLocked) {
12673 final int pid = Binder.getCallingPid();
12674 proc = mPidsSelfLocked.get(pid);
12676 if (proc != null && mInVrMode && tid >= 0) {
12677 // ensure the tid belongs to the process
12678 if (!Process.isThreadInProcess(pid, tid)) {
12679 throw new IllegalArgumentException("VR thread does not belong to process");
12682 // reset existing VR thread to CFS if this thread still exists and belongs to
12683 // the calling process
12684 if (proc.vrThreadTid != 0
12685 && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12687 Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12688 } catch (IllegalArgumentException e) {
12689 // Ignore this. Only occurs in race condition where previous VR thread
12690 // was destroyed during this method call.
12694 proc.vrThreadTid = tid;
12696 // promote to FIFO now if the tid is non-zero
12698 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12699 proc.vrThreadTid > 0) {
12700 Process.setThreadScheduler(proc.vrThreadTid,
12701 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12703 } catch (IllegalArgumentException e) {
12704 Slog.e(TAG, "Failed to set scheduling policy, thread does"
12705 + " not exist:\n" + e);
12713 public void setRenderThread(int tid) {
12714 synchronized (this) {
12715 ProcessRecord proc;
12716 synchronized (mPidsSelfLocked) {
12717 int pid = Binder.getCallingPid();
12718 proc = mPidsSelfLocked.get(pid);
12719 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12720 // ensure the tid belongs to the process
12721 if (!Process.isThreadInProcess(pid, tid)) {
12722 throw new IllegalArgumentException(
12723 "Render thread does not belong to process");
12725 proc.renderThreadTid = tid;
12726 if (DEBUG_OOM_ADJ) {
12727 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12729 // promote to FIFO now
12730 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12731 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12732 if (mUseFifoUiScheduling) {
12733 Process.setThreadScheduler(proc.renderThreadTid,
12734 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12736 Process.setThreadPriority(proc.renderThreadTid, -10);
12740 if (DEBUG_OOM_ADJ) {
12741 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12742 "PID: " + pid + ", TID: " + tid + " FIFO: " +
12743 mUseFifoUiScheduling);
12751 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12752 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12753 throw new UnsupportedOperationException("VR mode not supported on this device!");
12756 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12759 synchronized (this) {
12760 r = ActivityRecord.isInStackLocked(token);
12764 throw new IllegalArgumentException();
12768 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12769 VrManagerInternal.NO_ERROR) {
12773 synchronized(this) {
12774 r.requestedVrComponent = (enabled) ? packageName : null;
12776 // Update associated state if this activity is currently focused
12777 if (r == mFocusedActivity) {
12778 applyUpdateVrModeLocked(r);
12785 public boolean isVrModePackageEnabled(ComponentName packageName) {
12786 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12787 throw new UnsupportedOperationException("VR mode not supported on this device!");
12790 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12792 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12793 VrManagerInternal.NO_ERROR;
12796 public boolean isTopActivityImmersive() {
12797 enforceNotIsolatedCaller("startActivity");
12798 synchronized (this) {
12799 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12800 return (r != null) ? r.immersive : false;
12805 public boolean isTopOfTask(IBinder token) {
12806 synchronized (this) {
12807 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12809 throw new IllegalArgumentException();
12811 return r.task.getTopActivity() == r;
12816 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12817 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12818 String msg = "Permission Denial: setHasTopUi() from pid="
12819 + Binder.getCallingPid()
12820 + ", uid=" + Binder.getCallingUid()
12821 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12823 throw new SecurityException(msg);
12825 final int pid = Binder.getCallingPid();
12826 final long origId = Binder.clearCallingIdentity();
12828 synchronized (this) {
12829 boolean changed = false;
12831 synchronized (mPidsSelfLocked) {
12832 pr = mPidsSelfLocked.get(pid);
12834 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12837 if (pr.hasTopUi != hasTopUi) {
12838 Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12839 pr.hasTopUi = hasTopUi;
12844 updateOomAdjLocked(pr);
12848 Binder.restoreCallingIdentity(origId);
12852 public final void enterSafeMode() {
12853 synchronized(this) {
12854 // It only makes sense to do this before the system is ready
12855 // and started launching other packages.
12856 if (!mSystemReady) {
12858 AppGlobals.getPackageManager().enterSafeMode();
12859 } catch (RemoteException e) {
12867 public final void showSafeModeOverlay() {
12868 View v = LayoutInflater.from(mContext).inflate(
12869 com.android.internal.R.layout.safe_mode, null);
12870 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12871 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12872 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12873 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12874 lp.gravity = Gravity.BOTTOM | Gravity.START;
12875 lp.format = v.getBackground().getOpacity();
12876 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12877 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12878 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12879 ((WindowManager)mContext.getSystemService(
12880 Context.WINDOW_SERVICE)).addView(v, lp);
12883 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12884 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12887 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12888 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12889 synchronized (stats) {
12890 if (mBatteryStatsService.isOnBattery()) {
12891 mBatteryStatsService.enforceCallingPermission();
12892 int MY_UID = Binder.getCallingUid();
12894 if (sender == null) {
12897 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12899 BatteryStatsImpl.Uid.Pkg pkg =
12900 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12901 sourcePkg != null ? sourcePkg : rec.key.packageName);
12902 pkg.noteWakeupAlarmLocked(tag);
12907 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12908 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12911 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12912 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12913 synchronized (stats) {
12914 mBatteryStatsService.enforceCallingPermission();
12915 int MY_UID = Binder.getCallingUid();
12917 if (sender == null) {
12920 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12922 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12926 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12927 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12930 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12931 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12932 synchronized (stats) {
12933 mBatteryStatsService.enforceCallingPermission();
12934 int MY_UID = Binder.getCallingUid();
12936 if (sender == null) {
12939 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12941 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12945 public boolean killPids(int[] pids, String pReason, boolean secure) {
12946 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12947 throw new SecurityException("killPids only available to the system");
12949 String reason = (pReason == null) ? "Unknown" : pReason;
12950 // XXX Note: don't acquire main activity lock here, because the window
12951 // manager calls in with its locks held.
12953 boolean killed = false;
12954 synchronized (mPidsSelfLocked) {
12956 for (int i=0; i<pids.length; i++) {
12957 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12958 if (proc != null) {
12959 int type = proc.setAdj;
12960 if (type > worstType) {
12966 // If the worst oom_adj is somewhere in the cached proc LRU range,
12967 // then constrain it so we will kill all cached procs.
12968 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12969 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12970 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12973 // If this is not a secure call, don't let it kill processes that
12975 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12976 worstType = ProcessList.SERVICE_ADJ;
12979 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12980 for (int i=0; i<pids.length; i++) {
12981 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12982 if (proc == null) {
12985 int adj = proc.setAdj;
12986 if (adj >= worstType && !proc.killedByAm) {
12987 proc.kill(reason, true);
12996 public void killUid(int appId, int userId, String reason) {
12997 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12998 synchronized (this) {
12999 final long identity = Binder.clearCallingIdentity();
13001 killPackageProcessesLocked(null, appId, userId,
13002 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13003 reason != null ? reason : "kill uid");
13005 Binder.restoreCallingIdentity(identity);
13011 public boolean killProcessesBelowForeground(String reason) {
13012 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13013 throw new SecurityException("killProcessesBelowForeground() only available to system");
13016 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13019 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13020 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13021 throw new SecurityException("killProcessesBelowAdj() only available to system");
13024 boolean killed = false;
13025 synchronized (mPidsSelfLocked) {
13026 final int size = mPidsSelfLocked.size();
13027 for (int i = 0; i < size; i++) {
13028 final int pid = mPidsSelfLocked.keyAt(i);
13029 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13030 if (proc == null) continue;
13032 final int adj = proc.setAdj;
13033 if (adj > belowAdj && !proc.killedByAm) {
13034 proc.kill(reason, true);
13043 public void hang(final IBinder who, boolean allowRestart) {
13044 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13045 != PackageManager.PERMISSION_GRANTED) {
13046 throw new SecurityException("Requires permission "
13047 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13050 final IBinder.DeathRecipient death = new DeathRecipient() {
13052 public void binderDied() {
13053 synchronized (this) {
13060 who.linkToDeath(death, 0);
13061 } catch (RemoteException e) {
13062 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13066 synchronized (this) {
13067 Watchdog.getInstance().setAllowRestart(allowRestart);
13068 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13069 synchronized (death) {
13070 while (who.isBinderAlive()) {
13073 } catch (InterruptedException e) {
13077 Watchdog.getInstance().setAllowRestart(true);
13082 public void restart() {
13083 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13084 != PackageManager.PERMISSION_GRANTED) {
13085 throw new SecurityException("Requires permission "
13086 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13089 Log.i(TAG, "Sending shutdown broadcast...");
13091 BroadcastReceiver br = new BroadcastReceiver() {
13092 @Override public void onReceive(Context context, Intent intent) {
13093 // Now the broadcast is done, finish up the low-level shutdown.
13094 Log.i(TAG, "Shutting down activity manager...");
13096 Log.i(TAG, "Shutdown complete, restarting!");
13097 Process.killProcess(Process.myPid());
13102 // First send the high-level shut down broadcast.
13103 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13104 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13105 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13106 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13107 mContext.sendOrderedBroadcastAsUser(intent,
13108 UserHandle.ALL, null, br, mHandler, 0, null, null);
13110 br.onReceive(mContext, intent);
13113 private long getLowRamTimeSinceIdle(long now) {
13114 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13118 public void performIdleMaintenance() {
13119 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13120 != PackageManager.PERMISSION_GRANTED) {
13121 throw new SecurityException("Requires permission "
13122 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13125 synchronized (this) {
13126 final long now = SystemClock.uptimeMillis();
13127 final long timeSinceLastIdle = now - mLastIdleTime;
13128 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13129 mLastIdleTime = now;
13130 mLowRamTimeSinceLastIdle = 0;
13131 if (mLowRamStartTime != 0) {
13132 mLowRamStartTime = now;
13135 StringBuilder sb = new StringBuilder(128);
13136 sb.append("Idle maintenance over ");
13137 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13138 sb.append(" low RAM for ");
13139 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13140 Slog.i(TAG, sb.toString());
13142 // If at least 1/3 of our time since the last idle period has been spent
13143 // with RAM low, then we want to kill processes.
13144 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13146 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13147 ProcessRecord proc = mLruProcesses.get(i);
13148 if (proc.notCachedSinceIdle) {
13149 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13150 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13151 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13152 if (doKilling && proc.initialIdlePss != 0
13153 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13154 sb = new StringBuilder(128);
13156 sb.append(proc.processName);
13157 sb.append(" in idle maint: pss=");
13158 sb.append(proc.lastPss);
13159 sb.append(", swapPss=");
13160 sb.append(proc.lastSwapPss);
13161 sb.append(", initialPss=");
13162 sb.append(proc.initialIdlePss);
13163 sb.append(", period=");
13164 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13165 sb.append(", lowRamPeriod=");
13166 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13167 Slog.wtfQuiet(TAG, sb.toString());
13168 proc.kill("idle maint (pss " + proc.lastPss
13169 + " from " + proc.initialIdlePss + ")", true);
13172 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13173 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13174 proc.notCachedSinceIdle = true;
13175 proc.initialIdlePss = 0;
13176 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13177 mTestPssMode, isSleepingLocked(), now);
13181 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13182 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13187 public void sendIdleJobTrigger() {
13188 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13189 != PackageManager.PERMISSION_GRANTED) {
13190 throw new SecurityException("Requires permission "
13191 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13194 final long ident = Binder.clearCallingIdentity();
13196 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13197 .setPackage("android")
13198 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13199 broadcastIntent(null, intent, null, null, 0, null, null, null,
13200 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13202 Binder.restoreCallingIdentity(ident);
13206 private void retrieveSettings() {
13207 final ContentResolver resolver = mContext.getContentResolver();
13208 final boolean freeformWindowManagement =
13209 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13210 || Settings.Global.getInt(
13211 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13212 final boolean supportsPictureInPicture =
13213 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13215 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13216 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13217 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13218 final boolean alwaysFinishActivities =
13219 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13220 final boolean lenientBackgroundCheck =
13221 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13222 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13223 final boolean forceResizable = Settings.Global.getInt(
13224 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13225 final boolean supportsLeanbackOnly =
13226 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13228 // Transfer any global setting for forcing RTL layout, into a System Property
13229 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13231 final Configuration configuration = new Configuration();
13232 Settings.System.getConfiguration(resolver, configuration);
13234 // This will take care of setting the correct layout direction flags
13235 configuration.setLayoutDirection(configuration.locale);
13238 synchronized (this) {
13239 mDebugApp = mOrigDebugApp = debugApp;
13240 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13241 mAlwaysFinishActivities = alwaysFinishActivities;
13242 mLenientBackgroundCheck = lenientBackgroundCheck;
13243 mSupportsLeanbackOnly = supportsLeanbackOnly;
13244 mForceResizableActivities = forceResizable;
13245 mWindowManager.setForceResizableTasks(mForceResizableActivities);
13246 if (supportsMultiWindow || forceResizable) {
13247 mSupportsMultiWindow = true;
13248 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13249 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13251 mSupportsMultiWindow = false;
13252 mSupportsFreeformWindowManagement = false;
13253 mSupportsPictureInPicture = false;
13255 // This happens before any activities are started, so we can
13256 // change mConfiguration in-place.
13257 updateConfigurationLocked(configuration, null, true);
13258 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13259 "Initial config: " + mConfiguration);
13261 // Load resources only after the current configuration has been set.
13262 final Resources res = mContext.getResources();
13263 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13264 mThumbnailWidth = res.getDimensionPixelSize(
13265 com.android.internal.R.dimen.thumbnail_width);
13266 mThumbnailHeight = res.getDimensionPixelSize(
13267 com.android.internal.R.dimen.thumbnail_height);
13268 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13269 com.android.internal.R.string.config_defaultPictureInPictureBounds));
13270 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13271 com.android.internal.R.string.config_appsNotReportingCrashes));
13272 if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13273 mFullscreenThumbnailScale = (float) res
13274 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13275 (float) mConfiguration.screenWidthDp;
13277 mFullscreenThumbnailScale = res.getFraction(
13278 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13283 public boolean testIsSystemReady() {
13284 // no need to synchronize(this) just to read & return the value
13285 return mSystemReady;
13288 public void systemReady(final Runnable goingCallback) {
13289 synchronized(this) {
13290 if (mSystemReady) {
13291 // If we're done calling all the receivers, run the next "boot phase" passed in
13292 // by the SystemServer
13293 if (goingCallback != null) {
13294 goingCallback.run();
13299 mLocalDeviceIdleController
13300 = LocalServices.getService(DeviceIdleController.LocalService.class);
13302 // Make sure we have the current profile info, since it is needed for security checks.
13303 mUserController.onSystemReady();
13304 mRecentTasks.onSystemReadyLocked();
13305 mAppOpsService.systemReady();
13306 mSystemReady = true;
13309 ArrayList<ProcessRecord> procsToKill = null;
13310 synchronized(mPidsSelfLocked) {
13311 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13312 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13313 if (!isAllowedWhileBooting(proc.info)){
13314 if (procsToKill == null) {
13315 procsToKill = new ArrayList<ProcessRecord>();
13317 procsToKill.add(proc);
13322 synchronized(this) {
13323 if (procsToKill != null) {
13324 for (int i=procsToKill.size()-1; i>=0; i--) {
13325 ProcessRecord proc = procsToKill.get(i);
13326 Slog.i(TAG, "Removing system update proc: " + proc);
13327 removeProcessLocked(proc, true, false, "system update done");
13331 // Now that we have cleaned up any update processes, we
13332 // are ready to start launching real processes and know that
13333 // we won't trample on them any more.
13334 mProcessesReady = true;
13337 Slog.i(TAG, "System now ready");
13338 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13339 SystemClock.uptimeMillis());
13341 synchronized(this) {
13342 // Make sure we have no pre-ready processes sitting around.
13344 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13345 ResolveInfo ri = mContext.getPackageManager()
13346 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13348 CharSequence errorMsg = null;
13350 ActivityInfo ai = ri.activityInfo;
13351 ApplicationInfo app = ai.applicationInfo;
13352 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13353 mTopAction = Intent.ACTION_FACTORY_TEST;
13355 mTopComponent = new ComponentName(app.packageName,
13358 errorMsg = mContext.getResources().getText(
13359 com.android.internal.R.string.factorytest_not_system);
13362 errorMsg = mContext.getResources().getText(
13363 com.android.internal.R.string.factorytest_no_action);
13365 if (errorMsg != null) {
13368 mTopComponent = null;
13369 Message msg = Message.obtain();
13370 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13371 msg.getData().putCharSequence("msg", errorMsg);
13372 mUiHandler.sendMessage(msg);
13377 retrieveSettings();
13378 final int currentUserId;
13379 synchronized (this) {
13380 currentUserId = mUserController.getCurrentUserIdLocked();
13381 readGrantedUriPermissionsLocked();
13384 if (goingCallback != null) goingCallback.run();
13386 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13387 Integer.toString(currentUserId), currentUserId);
13388 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13389 Integer.toString(currentUserId), currentUserId);
13390 mSystemServiceManager.startUser(currentUserId);
13392 synchronized (this) {
13393 // Only start up encryption-aware persistent apps; once user is
13394 // unlocked we'll come back around and start unaware apps
13395 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13397 // Start up initial activity.
13399 // Enable home activity for system user, so that the system can always boot
13400 if (UserManager.isSplitSystemUser()) {
13401 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13403 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13404 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13405 UserHandle.USER_SYSTEM);
13406 } catch (RemoteException e) {
13407 throw e.rethrowAsRuntimeException();
13410 startHomeActivityLocked(currentUserId, "systemReady");
13413 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13414 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13415 + " data partition or your device will be unstable.");
13416 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13418 } catch (RemoteException e) {
13421 if (!Build.isBuildConsistent()) {
13422 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13423 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13426 long ident = Binder.clearCallingIdentity();
13428 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13429 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13430 | Intent.FLAG_RECEIVER_FOREGROUND);
13431 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13432 broadcastIntentLocked(null, null, intent,
13433 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13434 null, false, false, MY_PID, Process.SYSTEM_UID,
13436 intent = new Intent(Intent.ACTION_USER_STARTING);
13437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13438 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13439 broadcastIntentLocked(null, null, intent,
13440 null, new IIntentReceiver.Stub() {
13442 public void performReceive(Intent intent, int resultCode, String data,
13443 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13444 throws RemoteException {
13447 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13448 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13449 } catch (Throwable t) {
13450 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13452 Binder.restoreCallingIdentity(ident);
13454 mStackSupervisor.resumeFocusedStackTopActivityLocked();
13455 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13459 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13460 synchronized (this) {
13461 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13465 void skipCurrentReceiverLocked(ProcessRecord app) {
13466 for (BroadcastQueue queue : mBroadcastQueues) {
13467 queue.skipCurrentReceiverLocked(app);
13472 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13473 * The application process will exit immediately after this call returns.
13474 * @param app object of the crashing app, null for the system server
13475 * @param crashInfo describing the exception
13477 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13478 ProcessRecord r = findAppProcess(app, "Crash");
13479 final String processName = app == null ? "system_server"
13480 : (r == null ? "unknown" : r.processName);
13482 handleApplicationCrashInner("crash", r, processName, crashInfo);
13485 /* Native crash reporting uses this inner version because it needs to be somewhat
13486 * decoupled from the AM-managed cleanup lifecycle
13488 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13489 ApplicationErrorReport.CrashInfo crashInfo) {
13490 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13491 UserHandle.getUserId(Binder.getCallingUid()), processName,
13492 r == null ? -1 : r.info.flags,
13493 crashInfo.exceptionClassName,
13494 crashInfo.exceptionMessage,
13495 crashInfo.throwFileName,
13496 crashInfo.throwLineNumber);
13498 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13500 mAppErrors.crashApplication(r, crashInfo);
13503 public void handleApplicationStrictModeViolation(
13506 StrictMode.ViolationInfo info) {
13507 ProcessRecord r = findAppProcess(app, "StrictMode");
13512 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13513 Integer stackFingerprint = info.hashCode();
13514 boolean logIt = true;
13515 synchronized (mAlreadyLoggedViolatedStacks) {
13516 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13518 // TODO: sub-sample into EventLog for these, with
13519 // the info.durationMillis? Then we'd get
13520 // the relative pain numbers, without logging all
13521 // the stack traces repeatedly. We'd want to do
13522 // likewise in the client code, which also does
13523 // dup suppression, before the Binder call.
13525 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13526 mAlreadyLoggedViolatedStacks.clear();
13528 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13532 logStrictModeViolationToDropBox(r, info);
13536 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13537 AppErrorResult result = new AppErrorResult();
13538 synchronized (this) {
13539 final long origId = Binder.clearCallingIdentity();
13541 Message msg = Message.obtain();
13542 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13543 HashMap<String, Object> data = new HashMap<String, Object>();
13544 data.put("result", result);
13545 data.put("app", r);
13546 data.put("violationMask", violationMask);
13547 data.put("info", info);
13549 mUiHandler.sendMessage(msg);
13551 Binder.restoreCallingIdentity(origId);
13553 int res = result.get();
13554 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13558 // Depending on the policy in effect, there could be a bunch of
13559 // these in quick succession so we try to batch these together to
13560 // minimize disk writes, number of dropbox entries, and maximize
13561 // compression, by having more fewer, larger records.
13562 private void logStrictModeViolationToDropBox(
13563 ProcessRecord process,
13564 StrictMode.ViolationInfo info) {
13565 if (info == null) {
13568 final boolean isSystemApp = process == null ||
13569 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13570 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13571 final String processName = process == null ? "unknown" : process.processName;
13572 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13573 final DropBoxManager dbox = (DropBoxManager)
13574 mContext.getSystemService(Context.DROPBOX_SERVICE);
13576 // Exit early if the dropbox isn't configured to accept this report type.
13577 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13579 boolean bufferWasEmpty;
13580 boolean needsFlush;
13581 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13582 synchronized (sb) {
13583 bufferWasEmpty = sb.length() == 0;
13584 appendDropBoxProcessHeaders(process, processName, sb);
13585 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13586 sb.append("System-App: ").append(isSystemApp).append("\n");
13587 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13588 if (info.violationNumThisLoop != 0) {
13589 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13591 if (info.numAnimationsRunning != 0) {
13592 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13594 if (info.broadcastIntentAction != null) {
13595 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13597 if (info.durationMillis != -1) {
13598 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13600 if (info.numInstances != -1) {
13601 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13603 if (info.tags != null) {
13604 for (String tag : info.tags) {
13605 sb.append("Span-Tag: ").append(tag).append("\n");
13609 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13610 sb.append(info.crashInfo.stackTrace);
13613 if (info.message != null) {
13614 sb.append(info.message);
13618 // Only buffer up to ~64k. Various logging bits truncate
13620 needsFlush = (sb.length() > 64 * 1024);
13623 // Flush immediately if the buffer's grown too large, or this
13624 // is a non-system app. Non-system apps are isolated with a
13625 // different tag & policy and not batched.
13627 // Batching is useful during internal testing with
13628 // StrictMode settings turned up high. Without batching,
13629 // thousands of separate files could be created on boot.
13630 if (!isSystemApp || needsFlush) {
13631 new Thread("Error dump: " + dropboxTag) {
13633 public void run() {
13635 synchronized (sb) {
13636 report = sb.toString();
13637 sb.delete(0, sb.length());
13640 if (report.length() != 0) {
13641 dbox.addText(dropboxTag, report);
13648 // System app batching:
13649 if (!bufferWasEmpty) {
13650 // An existing dropbox-writing thread is outstanding, so
13651 // we don't need to start it up. The existing thread will
13652 // catch the buffer appends we just did.
13656 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13657 // (After this point, we shouldn't access AMS internal data structures.)
13658 new Thread("Error dump: " + dropboxTag) {
13660 public void run() {
13661 // 5 second sleep to let stacks arrive and be batched together
13663 Thread.sleep(5000); // 5 seconds
13664 } catch (InterruptedException e) {}
13666 String errorReport;
13667 synchronized (mStrictModeBuffer) {
13668 errorReport = mStrictModeBuffer.toString();
13669 if (errorReport.length() == 0) {
13672 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13673 mStrictModeBuffer.trimToSize();
13675 dbox.addText(dropboxTag, errorReport);
13681 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13682 * @param app object of the crashing app, null for the system server
13683 * @param tag reported by the caller
13684 * @param system whether this wtf is coming from the system
13685 * @param crashInfo describing the context of the error
13686 * @return true if the process should exit immediately (WTF is fatal)
13688 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13689 final ApplicationErrorReport.CrashInfo crashInfo) {
13690 final int callingUid = Binder.getCallingUid();
13691 final int callingPid = Binder.getCallingPid();
13694 // If this is coming from the system, we could very well have low-level
13695 // system locks held, so we want to do this all asynchronously. And we
13696 // never want this to become fatal, so there is that too.
13697 mHandler.post(new Runnable() {
13698 @Override public void run() {
13699 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13705 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13708 if (r != null && r.pid != Process.myPid() &&
13709 Settings.Global.getInt(mContext.getContentResolver(),
13710 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13711 mAppErrors.crashApplication(r, crashInfo);
13718 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13719 final ApplicationErrorReport.CrashInfo crashInfo) {
13720 final ProcessRecord r = findAppProcess(app, "WTF");
13721 final String processName = app == null ? "system_server"
13722 : (r == null ? "unknown" : r.processName);
13724 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13725 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13727 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13733 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13734 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13736 private ProcessRecord findAppProcess(IBinder app, String reason) {
13741 synchronized (this) {
13742 final int NP = mProcessNames.getMap().size();
13743 for (int ip=0; ip<NP; ip++) {
13744 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13745 final int NA = apps.size();
13746 for (int ia=0; ia<NA; ia++) {
13747 ProcessRecord p = apps.valueAt(ia);
13748 if (p.thread != null && p.thread.asBinder() == app) {
13754 Slog.w(TAG, "Can't find mystery application for " + reason
13755 + " from pid=" + Binder.getCallingPid()
13756 + " uid=" + Binder.getCallingUid() + ": " + app);
13762 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13763 * to append various headers to the dropbox log text.
13765 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13766 StringBuilder sb) {
13767 // Watchdog thread ends up invoking this function (with
13768 // a null ProcessRecord) to add the stack file to dropbox.
13769 // Do not acquire a lock on this (am) in such cases, as it
13770 // could cause a potential deadlock, if and when watchdog
13771 // is invoked due to unavailability of lock on am and it
13772 // would prevent watchdog from killing system_server.
13773 if (process == null) {
13774 sb.append("Process: ").append(processName).append("\n");
13777 // Note: ProcessRecord 'process' is guarded by the service
13778 // instance. (notably process.pkgList, which could otherwise change
13779 // concurrently during execution of this method)
13780 synchronized (this) {
13781 sb.append("Process: ").append(processName).append("\n");
13782 int flags = process.info.flags;
13783 IPackageManager pm = AppGlobals.getPackageManager();
13784 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13785 for (int ip=0; ip<process.pkgList.size(); ip++) {
13786 String pkg = process.pkgList.keyAt(ip);
13787 sb.append("Package: ").append(pkg);
13789 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13791 sb.append(" v").append(pi.versionCode);
13792 if (pi.versionName != null) {
13793 sb.append(" (").append(pi.versionName).append(")");
13796 } catch (RemoteException e) {
13797 Slog.e(TAG, "Error getting package info: " + pkg, e);
13804 private static String processClass(ProcessRecord process) {
13805 if (process == null || process.pid == MY_PID) {
13806 return "system_server";
13807 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13808 return "system_app";
13814 private volatile long mWtfClusterStart;
13815 private volatile int mWtfClusterCount;
13818 * Write a description of an error (crash, WTF, ANR) to the drop box.
13819 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13820 * @param process which caused the error, null means the system server
13821 * @param activity which triggered the error, null if unknown
13822 * @param parent activity related to the error, null if unknown
13823 * @param subject line related to the error, null if absent
13824 * @param report in long form describing the error, null if absent
13825 * @param dataFile text file to include in the report, null if none
13826 * @param crashInfo giving an application stack trace, null if absent
13828 public void addErrorToDropBox(String eventType,
13829 ProcessRecord process, String processName, ActivityRecord activity,
13830 ActivityRecord parent, String subject,
13831 final String report, final File dataFile,
13832 final ApplicationErrorReport.CrashInfo crashInfo) {
13833 // NOTE -- this must never acquire the ActivityManagerService lock,
13834 // otherwise the watchdog may be prevented from resetting the system.
13836 final String dropboxTag = processClass(process) + "_" + eventType;
13837 final DropBoxManager dbox = (DropBoxManager)
13838 mContext.getSystemService(Context.DROPBOX_SERVICE);
13840 // Exit early if the dropbox isn't configured to accept this report type.
13841 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13843 // Rate-limit how often we're willing to do the heavy lifting below to
13844 // collect and record logs; currently 5 logs per 10 second period.
13845 final long now = SystemClock.elapsedRealtime();
13846 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13847 mWtfClusterStart = now;
13848 mWtfClusterCount = 1;
13850 if (mWtfClusterCount++ >= 5) return;
13853 final StringBuilder sb = new StringBuilder(1024);
13854 appendDropBoxProcessHeaders(process, processName, sb);
13855 if (process != null) {
13856 sb.append("Foreground: ")
13857 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13860 if (activity != null) {
13861 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13863 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13864 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13866 if (parent != null && parent != activity) {
13867 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13869 if (subject != null) {
13870 sb.append("Subject: ").append(subject).append("\n");
13872 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13873 if (Debug.isDebuggerConnected()) {
13874 sb.append("Debugger: Connected\n");
13878 // Do the rest in a worker thread to avoid blocking the caller on I/O
13879 // (After this point, we shouldn't access AMS internal data structures.)
13880 Thread worker = new Thread("Error dump: " + dropboxTag) {
13882 public void run() {
13883 if (report != null) {
13887 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13888 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13889 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13890 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13892 if (dataFile != null && maxDataFileSize > 0) {
13894 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13895 "\n\n[[TRUNCATED]]"));
13896 } catch (IOException e) {
13897 Slog.e(TAG, "Error reading " + dataFile, e);
13900 if (crashInfo != null && crashInfo.stackTrace != null) {
13901 sb.append(crashInfo.stackTrace);
13907 // Merge several logcat streams, and take the last N lines
13908 InputStreamReader input = null;
13910 java.lang.Process logcat = new ProcessBuilder(
13911 "/system/bin/timeout", "-k", "15s", "10s",
13912 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13913 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13914 .redirectErrorStream(true).start();
13916 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13917 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13918 input = new InputStreamReader(logcat.getInputStream());
13921 char[] buf = new char[8192];
13922 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13923 } catch (IOException e) {
13924 Slog.e(TAG, "Error running logcat", e);
13926 if (input != null) try { input.close(); } catch (IOException e) {}
13930 dbox.addText(dropboxTag, sb.toString());
13934 if (process == null) {
13935 // If process is null, we are being called from some internal code
13936 // and may be about to die -- run this synchronously.
13944 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13945 enforceNotIsolatedCaller("getProcessesInErrorState");
13946 // assume our apps are happy - lazy create the list
13947 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13949 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13950 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13951 int userId = UserHandle.getUserId(Binder.getCallingUid());
13953 synchronized (this) {
13955 // iterate across all processes
13956 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13957 ProcessRecord app = mLruProcesses.get(i);
13958 if (!allUsers && app.userId != userId) {
13961 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13962 // This one's in trouble, so we'll generate a report for it
13963 // crashes are higher priority (in case there's a crash *and* an anr)
13964 ActivityManager.ProcessErrorStateInfo report = null;
13965 if (app.crashing) {
13966 report = app.crashingReport;
13967 } else if (app.notResponding) {
13968 report = app.notRespondingReport;
13971 if (report != null) {
13972 if (errList == null) {
13973 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13975 errList.add(report);
13977 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13978 " crashing = " + app.crashing +
13979 " notResponding = " + app.notResponding);
13988 static int procStateToImportance(int procState, int memAdj,
13989 ActivityManager.RunningAppProcessInfo currApp) {
13990 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13991 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13992 currApp.lru = memAdj;
13999 private void fillInProcMemInfo(ProcessRecord app,
14000 ActivityManager.RunningAppProcessInfo outInfo) {
14001 outInfo.pid = app.pid;
14002 outInfo.uid = app.info.uid;
14003 if (mHeavyWeightProcess == app) {
14004 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14006 if (app.persistent) {
14007 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14009 if (app.activities.size() > 0) {
14010 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14012 outInfo.lastTrimLevel = app.trimMemoryLevel;
14013 int adj = app.curAdj;
14014 int procState = app.curProcState;
14015 outInfo.importance = procStateToImportance(procState, adj, outInfo);
14016 outInfo.importanceReasonCode = app.adjTypeCode;
14017 outInfo.processState = app.curProcState;
14021 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14022 enforceNotIsolatedCaller("getRunningAppProcesses");
14024 final int callingUid = Binder.getCallingUid();
14026 // Lazy instantiation of list
14027 List<ActivityManager.RunningAppProcessInfo> runList = null;
14028 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14029 callingUid) == PackageManager.PERMISSION_GRANTED;
14030 final int userId = UserHandle.getUserId(callingUid);
14031 final boolean allUids = isGetTasksAllowed(
14032 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14034 synchronized (this) {
14035 // Iterate across all processes
14036 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14037 ProcessRecord app = mLruProcesses.get(i);
14038 if ((!allUsers && app.userId != userId)
14039 || (!allUids && app.uid != callingUid)) {
14042 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14043 // Generate process state info for running application
14044 ActivityManager.RunningAppProcessInfo currApp =
14045 new ActivityManager.RunningAppProcessInfo(app.processName,
14046 app.pid, app.getPackageList());
14047 fillInProcMemInfo(app, currApp);
14048 if (app.adjSource instanceof ProcessRecord) {
14049 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14050 currApp.importanceReasonImportance =
14051 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14052 app.adjSourceProcState);
14053 } else if (app.adjSource instanceof ActivityRecord) {
14054 ActivityRecord r = (ActivityRecord)app.adjSource;
14055 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14057 if (app.adjTarget instanceof ComponentName) {
14058 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14060 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14061 // + " lru=" + currApp.lru);
14062 if (runList == null) {
14063 runList = new ArrayList<>();
14065 runList.add(currApp);
14073 public List<ApplicationInfo> getRunningExternalApplications() {
14074 enforceNotIsolatedCaller("getRunningExternalApplications");
14075 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14076 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14077 if (runningApps != null && runningApps.size() > 0) {
14078 Set<String> extList = new HashSet<String>();
14079 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14080 if (app.pkgList != null) {
14081 for (String pkg : app.pkgList) {
14086 IPackageManager pm = AppGlobals.getPackageManager();
14087 for (String pkg : extList) {
14089 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14090 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14093 } catch (RemoteException e) {
14101 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14102 enforceNotIsolatedCaller("getMyMemoryState");
14103 synchronized (this) {
14104 ProcessRecord proc;
14105 synchronized (mPidsSelfLocked) {
14106 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14108 fillInProcMemInfo(proc, outInfo);
14113 public int getMemoryTrimLevel() {
14114 enforceNotIsolatedCaller("getMyMemoryState");
14115 synchronized (this) {
14116 return mLastMemoryLevel;
14121 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14122 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14123 (new ActivityManagerShellCommand(this, false)).exec(
14124 this, in, out, err, args, resultReceiver);
14128 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14129 if (checkCallingPermission(android.Manifest.permission.DUMP)
14130 != PackageManager.PERMISSION_GRANTED) {
14131 pw.println("Permission Denial: can't dump ActivityManager from from pid="
14132 + Binder.getCallingPid()
14133 + ", uid=" + Binder.getCallingUid()
14134 + " without permission "
14135 + android.Manifest.permission.DUMP);
14139 boolean dumpAll = false;
14140 boolean dumpClient = false;
14141 boolean dumpCheckin = false;
14142 boolean dumpCheckinFormat = false;
14143 String dumpPackage = null;
14146 while (opti < args.length) {
14147 String opt = args[opti];
14148 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14152 if ("-a".equals(opt)) {
14154 } else if ("-c".equals(opt)) {
14156 } else if ("-p".equals(opt)) {
14157 if (opti < args.length) {
14158 dumpPackage = args[opti];
14161 pw.println("Error: -p option requires package argument");
14165 } else if ("--checkin".equals(opt)) {
14166 dumpCheckin = dumpCheckinFormat = true;
14167 } else if ("-C".equals(opt)) {
14168 dumpCheckinFormat = true;
14169 } else if ("-h".equals(opt)) {
14170 ActivityManagerShellCommand.dumpHelp(pw, true);
14173 pw.println("Unknown argument: " + opt + "; use -h for help");
14177 long origId = Binder.clearCallingIdentity();
14178 boolean more = false;
14179 // Is the caller requesting to dump a particular piece of data?
14180 if (opti < args.length) {
14181 String cmd = args[opti];
14183 if ("activities".equals(cmd) || "a".equals(cmd)) {
14184 synchronized (this) {
14185 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14187 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14188 synchronized (this) {
14189 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14191 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14194 if (opti >= args.length) {
14196 newArgs = EMPTY_STRING_ARRAY;
14198 dumpPackage = args[opti];
14200 newArgs = new String[args.length - opti];
14201 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14202 args.length - opti);
14204 synchronized (this) {
14205 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14207 } else if ("broadcast-stats".equals(cmd)) {
14210 if (opti >= args.length) {
14212 newArgs = EMPTY_STRING_ARRAY;
14214 dumpPackage = args[opti];
14216 newArgs = new String[args.length - opti];
14217 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14218 args.length - opti);
14220 synchronized (this) {
14221 if (dumpCheckinFormat) {
14222 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14225 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14228 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14231 if (opti >= args.length) {
14233 newArgs = EMPTY_STRING_ARRAY;
14235 dumpPackage = args[opti];
14237 newArgs = new String[args.length - opti];
14238 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14239 args.length - opti);
14241 synchronized (this) {
14242 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14244 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14247 if (opti >= args.length) {
14249 newArgs = EMPTY_STRING_ARRAY;
14251 dumpPackage = args[opti];
14253 newArgs = new String[args.length - opti];
14254 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14255 args.length - opti);
14257 synchronized (this) {
14258 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14260 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14261 synchronized (this) {
14262 dumpOomLocked(fd, pw, args, opti, true);
14264 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14265 synchronized (this) {
14266 dumpPermissionsLocked(fd, pw, args, opti, true, null);
14268 } else if ("provider".equals(cmd)) {
14271 if (opti >= args.length) {
14273 newArgs = EMPTY_STRING_ARRAY;
14277 newArgs = new String[args.length - opti];
14278 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14280 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14281 pw.println("No providers match: " + name);
14282 pw.println("Use -h for help.");
14284 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14285 synchronized (this) {
14286 dumpProvidersLocked(fd, pw, args, opti, true, null);
14288 } else if ("service".equals(cmd)) {
14291 if (opti >= args.length) {
14293 newArgs = EMPTY_STRING_ARRAY;
14297 newArgs = new String[args.length - opti];
14298 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14299 args.length - opti);
14301 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14302 pw.println("No services match: " + name);
14303 pw.println("Use -h for help.");
14305 } else if ("package".equals(cmd)) {
14307 if (opti >= args.length) {
14308 pw.println("package: no package name specified");
14309 pw.println("Use -h for help.");
14311 dumpPackage = args[opti];
14313 newArgs = new String[args.length - opti];
14314 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14315 args.length - opti);
14320 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14321 synchronized (this) {
14322 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14324 } else if ("services".equals(cmd) || "s".equals(cmd)) {
14326 ActiveServices.ServiceDumper dumper;
14327 synchronized (this) {
14328 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14331 dumper.dumpWithClient();
14333 synchronized (this) {
14334 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14335 dumpPackage).dumpLocked();
14338 } else if ("locks".equals(cmd)) {
14339 LockGuard.dump(fd, pw, args);
14341 // Dumping a single activity?
14342 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14343 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14344 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14346 pw.println("Bad activity command, or no activities match: " + cmd);
14347 pw.println("Use -h for help.");
14352 Binder.restoreCallingIdentity(origId);
14357 // No piece of data specified, dump everything.
14358 if (dumpCheckinFormat) {
14359 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14360 } else if (dumpClient) {
14361 ActiveServices.ServiceDumper sdumper;
14362 synchronized (this) {
14363 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14366 pw.println("-------------------------------------------------------------------------------");
14368 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14371 pw.println("-------------------------------------------------------------------------------");
14373 if (dumpAll || dumpPackage != null) {
14374 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14377 pw.println("-------------------------------------------------------------------------------");
14380 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14383 pw.println("-------------------------------------------------------------------------------");
14385 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14388 pw.println("-------------------------------------------------------------------------------");
14390 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14393 sdumper.dumpWithClient();
14395 synchronized (this) {
14397 pw.println("-------------------------------------------------------------------------------");
14399 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14402 pw.println("-------------------------------------------------------------------------------");
14404 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14405 if (mAssociations.size() > 0) {
14408 pw.println("-------------------------------------------------------------------------------");
14410 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14414 pw.println("-------------------------------------------------------------------------------");
14416 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14420 synchronized (this) {
14421 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14424 pw.println("-------------------------------------------------------------------------------");
14426 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14429 pw.println("-------------------------------------------------------------------------------");
14431 if (dumpAll || dumpPackage != null) {
14432 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14435 pw.println("-------------------------------------------------------------------------------");
14438 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14441 pw.println("-------------------------------------------------------------------------------");
14443 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14446 pw.println("-------------------------------------------------------------------------------");
14448 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14452 pw.println("-------------------------------------------------------------------------------");
14454 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14457 pw.println("-------------------------------------------------------------------------------");
14459 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14460 if (mAssociations.size() > 0) {
14463 pw.println("-------------------------------------------------------------------------------");
14465 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14469 pw.println("-------------------------------------------------------------------------------");
14471 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14474 Binder.restoreCallingIdentity(origId);
14477 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14478 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14479 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14481 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14483 boolean needSep = printedAnything;
14485 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14486 dumpPackage, needSep, " mFocusedActivity: ");
14488 printedAnything = true;
14492 if (dumpPackage == null) {
14497 printedAnything = true;
14498 mStackSupervisor.dump(pw, " ");
14501 if (!printedAnything) {
14502 pw.println(" (nothing)");
14506 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14507 int opti, boolean dumpAll, String dumpPackage) {
14508 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14510 boolean printedAnything = false;
14512 if (mRecentTasks != null && mRecentTasks.size() > 0) {
14513 boolean printedHeader = false;
14515 final int N = mRecentTasks.size();
14516 for (int i=0; i<N; i++) {
14517 TaskRecord tr = mRecentTasks.get(i);
14518 if (dumpPackage != null) {
14519 if (tr.realActivity == null ||
14520 !dumpPackage.equals(tr.realActivity)) {
14524 if (!printedHeader) {
14525 pw.println(" Recent tasks:");
14526 printedHeader = true;
14527 printedAnything = true;
14529 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
14532 mRecentTasks.get(i).dump(pw, " ");
14537 if (!printedAnything) {
14538 pw.println(" (nothing)");
14542 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14543 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14544 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14547 if (dumpPackage != null) {
14548 IPackageManager pm = AppGlobals.getPackageManager();
14550 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14551 } catch (RemoteException e) {
14555 boolean printedAnything = false;
14557 final long now = SystemClock.uptimeMillis();
14559 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14560 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14561 = mAssociations.valueAt(i1);
14562 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14563 SparseArray<ArrayMap<String, Association>> sourceUids
14564 = targetComponents.valueAt(i2);
14565 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14566 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14567 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14568 Association ass = sourceProcesses.valueAt(i4);
14569 if (dumpPackage != null) {
14570 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14571 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14575 printedAnything = true;
14577 pw.print(ass.mTargetProcess);
14579 UserHandle.formatUid(pw, ass.mTargetUid);
14581 pw.print(ass.mSourceProcess);
14583 UserHandle.formatUid(pw, ass.mSourceUid);
14586 pw.print(ass.mTargetComponent.flattenToShortString());
14589 long dur = ass.mTime;
14590 if (ass.mNesting > 0) {
14591 dur += now - ass.mStartTime;
14593 TimeUtils.formatDuration(dur, pw);
14595 pw.print(ass.mCount);
14596 pw.print(" times)");
14598 for (int i=0; i<ass.mStateTimes.length; i++) {
14599 long amt = ass.mStateTimes[i];
14600 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14601 amt += now - ass.mLastStateUptime;
14605 pw.print(ProcessList.makeProcStateString(
14606 i + ActivityManager.MIN_PROCESS_STATE));
14608 TimeUtils.formatDuration(amt, pw);
14609 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14615 if (ass.mNesting > 0) {
14616 pw.print(" Currently active: ");
14617 TimeUtils.formatDuration(now - ass.mStartTime, pw);
14626 if (!printedAnything) {
14627 pw.println(" (nothing)");
14631 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14632 String header, boolean needSep) {
14633 boolean printed = false;
14634 int whichAppId = -1;
14635 if (dumpPackage != null) {
14637 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14639 whichAppId = UserHandle.getAppId(info.uid);
14640 } catch (NameNotFoundException e) {
14641 e.printStackTrace();
14644 for (int i=0; i<uids.size(); i++) {
14645 UidRecord uidRec = uids.valueAt(i);
14646 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14655 pw.println(header);
14658 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14659 pw.print(": "); pw.println(uidRec);
14664 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14665 int opti, boolean dumpAll, String dumpPackage) {
14666 boolean needSep = false;
14667 boolean printedAnything = false;
14670 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14673 final int NP = mProcessNames.getMap().size();
14674 for (int ip=0; ip<NP; ip++) {
14675 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14676 final int NA = procs.size();
14677 for (int ia=0; ia<NA; ia++) {
14678 ProcessRecord r = procs.valueAt(ia);
14679 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14683 pw.println(" All known processes:");
14685 printedAnything = true;
14687 pw.print(r.persistent ? " *PERS*" : " *APP*");
14688 pw.print(" UID "); pw.print(procs.keyAt(ia));
14689 pw.print(" "); pw.println(r);
14691 if (r.persistent) {
14698 if (mIsolatedProcesses.size() > 0) {
14699 boolean printed = false;
14700 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14701 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14702 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14709 pw.println(" Isolated process list (sorted by uid):");
14710 printedAnything = true;
14714 pw.println(String.format("%sIsolated #%2d: %s",
14715 " ", i, r.toString()));
14719 if (mActiveUids.size() > 0) {
14720 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14721 printedAnything = needSep = true;
14724 if (mValidateUids.size() > 0) {
14725 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14726 printedAnything = needSep = true;
14730 if (mLruProcesses.size() > 0) {
14734 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14735 pw.print(" total, non-act at ");
14736 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14737 pw.print(", non-svc at ");
14738 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14740 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14742 printedAnything = true;
14745 if (dumpAll || dumpPackage != null) {
14746 synchronized (mPidsSelfLocked) {
14747 boolean printed = false;
14748 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14749 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14750 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14754 if (needSep) pw.println();
14756 pw.println(" PID mappings:");
14758 printedAnything = true;
14760 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14761 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14766 if (mForegroundProcesses.size() > 0) {
14767 synchronized (mPidsSelfLocked) {
14768 boolean printed = false;
14769 for (int i=0; i<mForegroundProcesses.size(); i++) {
14770 ProcessRecord r = mPidsSelfLocked.get(
14771 mForegroundProcesses.valueAt(i).pid);
14772 if (dumpPackage != null && (r == null
14773 || !r.pkgList.containsKey(dumpPackage))) {
14777 if (needSep) pw.println();
14779 pw.println(" Foreground Processes:");
14781 printedAnything = true;
14783 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14784 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14789 if (mPersistentStartingProcesses.size() > 0) {
14790 if (needSep) pw.println();
14792 printedAnything = true;
14793 pw.println(" Persisent processes that are starting:");
14794 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14795 "Starting Norm", "Restarting PERS", dumpPackage);
14798 if (mRemovedProcesses.size() > 0) {
14799 if (needSep) pw.println();
14801 printedAnything = true;
14802 pw.println(" Processes that are being removed:");
14803 dumpProcessList(pw, this, mRemovedProcesses, " ",
14804 "Removed Norm", "Removed PERS", dumpPackage);
14807 if (mProcessesOnHold.size() > 0) {
14808 if (needSep) pw.println();
14810 printedAnything = true;
14811 pw.println(" Processes that are on old until the system is ready:");
14812 dumpProcessList(pw, this, mProcessesOnHold, " ",
14813 "OnHold Norm", "OnHold PERS", dumpPackage);
14816 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14818 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14820 printedAnything = true;
14823 if (dumpPackage == null) {
14826 mUserController.dump(pw, dumpAll);
14828 if (mHomeProcess != null && (dumpPackage == null
14829 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14834 pw.println(" mHomeProcess: " + mHomeProcess);
14836 if (mPreviousProcess != null && (dumpPackage == null
14837 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14842 pw.println(" mPreviousProcess: " + mPreviousProcess);
14845 StringBuilder sb = new StringBuilder(128);
14846 sb.append(" mPreviousProcessVisibleTime: ");
14847 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14850 if (mHeavyWeightProcess != null && (dumpPackage == null
14851 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14856 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14858 if (dumpPackage == null) {
14859 pw.println(" mConfiguration: " + mConfiguration);
14862 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14863 if (mCompatModePackages.getPackages().size() > 0) {
14864 boolean printed = false;
14865 for (Map.Entry<String, Integer> entry
14866 : mCompatModePackages.getPackages().entrySet()) {
14867 String pkg = entry.getKey();
14868 int mode = entry.getValue();
14869 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14873 pw.println(" mScreenCompatPackages:");
14876 pw.print(" "); pw.print(pkg); pw.print(": ");
14877 pw.print(mode); pw.println();
14881 if (dumpPackage == null) {
14882 pw.println(" mWakefulness="
14883 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14884 pw.println(" mSleepTokens=" + mSleepTokens);
14885 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14886 + lockScreenShownToString());
14887 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14888 if (mRunningVoice != null) {
14889 pw.println(" mRunningVoice=" + mRunningVoice);
14890 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14893 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14894 || mOrigWaitForDebugger) {
14895 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14896 || dumpPackage.equals(mOrigDebugApp)) {
14901 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14902 + " mDebugTransient=" + mDebugTransient
14903 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14906 if (mCurAppTimeTracker != null) {
14907 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14909 if (mMemWatchProcesses.getMap().size() > 0) {
14910 pw.println(" Mem watch processes:");
14911 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14912 = mMemWatchProcesses.getMap();
14913 for (int i=0; i<procs.size(); i++) {
14914 final String proc = procs.keyAt(i);
14915 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14916 for (int j=0; j<uids.size(); j++) {
14921 StringBuilder sb = new StringBuilder();
14922 sb.append(" ").append(proc).append('/');
14923 UserHandle.formatUid(sb, uids.keyAt(j));
14924 Pair<Long, String> val = uids.valueAt(j);
14925 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14926 if (val.second != null) {
14927 sb.append(", report to ").append(val.second);
14929 pw.println(sb.toString());
14932 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14933 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14934 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14935 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14937 if (mTrackAllocationApp != null) {
14938 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14943 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14946 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14947 || mProfileFd != null) {
14948 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14953 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14954 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14955 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14956 + mAutoStopProfiler);
14957 pw.println(" mProfileType=" + mProfileType);
14960 if (mNativeDebuggingApp != null) {
14961 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14966 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14969 if (dumpPackage == null) {
14970 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14971 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14972 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14974 if (mController != null) {
14975 pw.println(" mController=" + mController
14976 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14979 pw.println(" Total persistent processes: " + numPers);
14980 pw.println(" mProcessesReady=" + mProcessesReady
14981 + " mSystemReady=" + mSystemReady
14982 + " mBooted=" + mBooted
14983 + " mFactoryTest=" + mFactoryTest);
14984 pw.println(" mBooting=" + mBooting
14985 + " mCallFinishBooting=" + mCallFinishBooting
14986 + " mBootAnimationComplete=" + mBootAnimationComplete);
14987 pw.print(" mLastPowerCheckRealtime=");
14988 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14990 pw.print(" mLastPowerCheckUptime=");
14991 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14993 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14994 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14995 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14996 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
14997 + " (" + mLruProcesses.size() + " total)"
14998 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14999 + " mNumServiceProcs=" + mNumServiceProcs
15000 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15001 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
15002 + " mLastMemoryLevel=" + mLastMemoryLevel
15003 + " mLastNumProcesses=" + mLastNumProcesses);
15004 long now = SystemClock.uptimeMillis();
15005 pw.print(" mLastIdleTime=");
15006 TimeUtils.formatDuration(now, mLastIdleTime, pw);
15007 pw.print(" mLowRamSinceLastIdle=");
15008 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15013 if (!printedAnything) {
15014 pw.println(" (nothing)");
15018 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15019 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15020 if (mProcessesToGc.size() > 0) {
15021 boolean printed = false;
15022 long now = SystemClock.uptimeMillis();
15023 for (int i=0; i<mProcessesToGc.size(); i++) {
15024 ProcessRecord proc = mProcessesToGc.get(i);
15025 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15029 if (needSep) pw.println();
15031 pw.println(" Processes that are waiting to GC:");
15034 pw.print(" Process "); pw.println(proc);
15035 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
15036 pw.print(", last gced=");
15037 pw.print(now-proc.lastRequestedGc);
15038 pw.print(" ms ago, last lowMem=");
15039 pw.print(now-proc.lastLowMemory);
15040 pw.println(" ms ago");
15047 void printOomLevel(PrintWriter pw, String name, int adj) {
15051 if (adj < 10) pw.print(' ');
15053 if (adj > -10) pw.print(' ');
15059 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15063 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15064 int opti, boolean dumpAll) {
15065 boolean needSep = false;
15067 if (mLruProcesses.size() > 0) {
15068 if (needSep) pw.println();
15070 pw.println(" OOM levels:");
15071 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15072 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15073 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15074 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15075 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15076 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15077 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15078 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15079 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15080 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15081 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15082 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15083 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15084 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15086 if (needSep) pw.println();
15087 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
15088 pw.print(" total, non-act at ");
15089 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15090 pw.print(", non-svc at ");
15091 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15093 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
15097 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15100 pw.println(" mHomeProcess: " + mHomeProcess);
15101 pw.println(" mPreviousProcess: " + mPreviousProcess);
15102 if (mHeavyWeightProcess != null) {
15103 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15110 * There are three ways to call this:
15111 * - no provider specified: dump all the providers
15112 * - a flattened component name that matched an existing provider was specified as the
15113 * first arg: dump that one provider
15114 * - the first arg isn't the flattened component name of an existing provider:
15115 * dump all providers whose component contains the first arg as a substring
15117 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15118 int opti, boolean dumpAll) {
15119 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15122 static class ItemMatcher {
15123 ArrayList<ComponentName> components;
15124 ArrayList<String> strings;
15125 ArrayList<Integer> objects;
15132 void build(String name) {
15133 ComponentName componentName = ComponentName.unflattenFromString(name);
15134 if (componentName != null) {
15135 if (components == null) {
15136 components = new ArrayList<ComponentName>();
15138 components.add(componentName);
15142 // Not a '/' separated full component name; maybe an object ID?
15144 objectId = Integer.parseInt(name, 16);
15145 if (objects == null) {
15146 objects = new ArrayList<Integer>();
15148 objects.add(objectId);
15150 } catch (RuntimeException e) {
15151 // Not an integer; just do string match.
15152 if (strings == null) {
15153 strings = new ArrayList<String>();
15161 int build(String[] args, int opti) {
15162 for (; opti<args.length; opti++) {
15163 String name = args[opti];
15164 if ("--".equals(name)) {
15172 boolean match(Object object, ComponentName comp) {
15176 if (components != null) {
15177 for (int i=0; i<components.size(); i++) {
15178 if (components.get(i).equals(comp)) {
15183 if (objects != null) {
15184 for (int i=0; i<objects.size(); i++) {
15185 if (System.identityHashCode(object) == objects.get(i)) {
15190 if (strings != null) {
15191 String flat = comp.flattenToString();
15192 for (int i=0; i<strings.size(); i++) {
15193 if (flat.contains(strings.get(i))) {
15203 * There are three things that cmd can be:
15204 * - a flattened component name that matches an existing activity
15205 * - the cmd arg isn't the flattened component name of an existing activity:
15206 * dump all activity whose component contains the cmd as a substring
15207 * - A hex number of the ActivityRecord object instance.
15209 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15210 int opti, boolean dumpAll) {
15211 ArrayList<ActivityRecord> activities;
15213 synchronized (this) {
15214 activities = mStackSupervisor.getDumpActivitiesLocked(name);
15217 if (activities.size() <= 0) {
15221 String[] newArgs = new String[args.length - opti];
15222 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15224 TaskRecord lastTask = null;
15225 boolean needSep = false;
15226 for (int i=activities.size()-1; i>=0; i--) {
15227 ActivityRecord r = activities.get(i);
15232 synchronized (this) {
15233 if (lastTask != r.task) {
15235 pw.print("TASK "); pw.print(lastTask.affinity);
15236 pw.print(" id="); pw.println(lastTask.taskId);
15238 lastTask.dump(pw, " ");
15242 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
15248 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15249 * there is a thread associated with the activity.
15251 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15252 final ActivityRecord r, String[] args, boolean dumpAll) {
15253 String innerPrefix = prefix + " ";
15254 synchronized (this) {
15255 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15256 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15258 if (r.app != null) pw.println(r.app.pid);
15259 else pw.println("(not running)");
15261 r.dump(pw, innerPrefix);
15264 if (r.app != null && r.app.thread != null) {
15265 // flush anything that is already in the PrintWriter since the thread is going
15266 // to write to the file descriptor directly
15269 TransferPipe tp = new TransferPipe();
15271 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15272 r.appToken, innerPrefix, args);
15277 } catch (IOException e) {
15278 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15279 } catch (RemoteException e) {
15280 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15285 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15286 int opti, boolean dumpAll, String dumpPackage) {
15287 boolean needSep = false;
15288 boolean onlyHistory = false;
15289 boolean printedAnything = false;
15291 if ("history".equals(dumpPackage)) {
15292 if (opti < args.length && "-s".equals(args[opti])) {
15295 onlyHistory = true;
15296 dumpPackage = null;
15299 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15300 if (!onlyHistory && dumpAll) {
15301 if (mRegisteredReceivers.size() > 0) {
15302 boolean printed = false;
15303 Iterator it = mRegisteredReceivers.values().iterator();
15304 while (it.hasNext()) {
15305 ReceiverList r = (ReceiverList)it.next();
15306 if (dumpPackage != null && (r.app == null ||
15307 !dumpPackage.equals(r.app.info.packageName))) {
15311 pw.println(" Registered Receivers:");
15314 printedAnything = true;
15316 pw.print(" * "); pw.println(r);
15321 if (mReceiverResolver.dump(pw, needSep ?
15322 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
15323 " ", dumpPackage, false, false)) {
15325 printedAnything = true;
15329 for (BroadcastQueue q : mBroadcastQueues) {
15330 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15331 printedAnything |= needSep;
15336 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15337 for (int user=0; user<mStickyBroadcasts.size(); user++) {
15342 printedAnything = true;
15343 pw.print(" Sticky broadcasts for user ");
15344 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15345 StringBuilder sb = new StringBuilder(128);
15346 for (Map.Entry<String, ArrayList<Intent>> ent
15347 : mStickyBroadcasts.valueAt(user).entrySet()) {
15348 pw.print(" * Sticky action "); pw.print(ent.getKey());
15351 ArrayList<Intent> intents = ent.getValue();
15352 final int N = intents.size();
15353 for (int i=0; i<N; i++) {
15355 sb.append(" Intent: ");
15356 intents.get(i).toShortString(sb, false, true, false, false);
15357 pw.println(sb.toString());
15358 Bundle bundle = intents.get(i).getExtras();
15359 if (bundle != null) {
15361 pw.println(bundle.toString());
15371 if (!onlyHistory && dumpAll) {
15373 for (BroadcastQueue queue : mBroadcastQueues) {
15374 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
15375 + queue.mBroadcastsScheduled);
15377 pw.println(" mHandler:");
15378 mHandler.dump(new PrintWriterPrinter(pw), " ");
15380 printedAnything = true;
15383 if (!printedAnything) {
15384 pw.println(" (nothing)");
15388 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15389 int opti, boolean dumpAll, String dumpPackage) {
15390 if (mCurBroadcastStats == null) {
15394 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15395 final long now = SystemClock.elapsedRealtime();
15396 if (mLastBroadcastStats != null) {
15397 pw.print(" Last stats (from ");
15398 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15400 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15402 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15403 - mLastBroadcastStats.mStartUptime, pw);
15404 pw.println(" uptime):");
15405 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15406 pw.println(" (nothing)");
15410 pw.print(" Current stats (from ");
15411 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15412 pw.print(" to now, ");
15413 TimeUtils.formatDuration(SystemClock.uptimeMillis()
15414 - mCurBroadcastStats.mStartUptime, pw);
15415 pw.println(" uptime):");
15416 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15417 pw.println(" (nothing)");
15421 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15422 int opti, boolean fullCheckin, String dumpPackage) {
15423 if (mCurBroadcastStats == null) {
15427 if (mLastBroadcastStats != null) {
15428 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15430 mLastBroadcastStats = null;
15434 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15436 mCurBroadcastStats = null;
15440 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15441 int opti, boolean dumpAll, String dumpPackage) {
15443 boolean printedAnything = false;
15445 ItemMatcher matcher = new ItemMatcher();
15446 matcher.build(args, opti);
15448 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15450 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15451 printedAnything |= needSep;
15453 if (mLaunchingProviders.size() > 0) {
15454 boolean printed = false;
15455 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15456 ContentProviderRecord r = mLaunchingProviders.get(i);
15457 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15461 if (needSep) pw.println();
15463 pw.println(" Launching content providers:");
15465 printedAnything = true;
15467 pw.print(" Launching #"); pw.print(i); pw.print(": ");
15472 if (!printedAnything) {
15473 pw.println(" (nothing)");
15477 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15478 int opti, boolean dumpAll, String dumpPackage) {
15479 boolean needSep = false;
15480 boolean printedAnything = false;
15482 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15484 if (mGrantedUriPermissions.size() > 0) {
15485 boolean printed = false;
15487 if (dumpPackage != null) {
15489 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15490 MATCH_UNINSTALLED_PACKAGES, 0);
15491 } catch (NameNotFoundException e) {
15495 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15496 int uid = mGrantedUriPermissions.keyAt(i);
15497 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15500 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15502 if (needSep) pw.println();
15504 pw.println(" Granted Uri Permissions:");
15506 printedAnything = true;
15508 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
15509 for (UriPermission perm : perms.values()) {
15510 pw.print(" "); pw.println(perm);
15512 perm.dump(pw, " ");
15518 if (!printedAnything) {
15519 pw.println(" (nothing)");
15523 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15524 int opti, boolean dumpAll, String dumpPackage) {
15525 boolean printed = false;
15527 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15529 if (mIntentSenderRecords.size() > 0) {
15530 Iterator<WeakReference<PendingIntentRecord>> it
15531 = mIntentSenderRecords.values().iterator();
15532 while (it.hasNext()) {
15533 WeakReference<PendingIntentRecord> ref = it.next();
15534 PendingIntentRecord rec = ref != null ? ref.get(): null;
15535 if (dumpPackage != null && (rec == null
15536 || !dumpPackage.equals(rec.key.packageName))) {
15541 pw.print(" * "); pw.println(rec);
15546 pw.print(" * "); pw.println(ref);
15552 pw.println(" (nothing)");
15556 private static final int dumpProcessList(PrintWriter pw,
15557 ActivityManagerService service, List list,
15558 String prefix, String normalLabel, String persistentLabel,
15559 String dumpPackage) {
15561 final int N = list.size()-1;
15562 for (int i=N; i>=0; i--) {
15563 ProcessRecord r = (ProcessRecord)list.get(i);
15564 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15567 pw.println(String.format("%s%s #%2d: %s",
15568 prefix, (r.persistent ? persistentLabel : normalLabel),
15570 if (r.persistent) {
15577 private static final boolean dumpProcessOomList(PrintWriter pw,
15578 ActivityManagerService service, List<ProcessRecord> origList,
15579 String prefix, String normalLabel, String persistentLabel,
15580 boolean inclDetails, String dumpPackage) {
15582 ArrayList<Pair<ProcessRecord, Integer>> list
15583 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15584 for (int i=0; i<origList.size(); i++) {
15585 ProcessRecord r = origList.get(i);
15586 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15589 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15592 if (list.size() <= 0) {
15596 Comparator<Pair<ProcessRecord, Integer>> comparator
15597 = new Comparator<Pair<ProcessRecord, Integer>>() {
15599 public int compare(Pair<ProcessRecord, Integer> object1,
15600 Pair<ProcessRecord, Integer> object2) {
15601 if (object1.first.setAdj != object2.first.setAdj) {
15602 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15604 if (object1.first.setProcState != object2.first.setProcState) {
15605 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15607 if (object1.second.intValue() != object2.second.intValue()) {
15608 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15614 Collections.sort(list, comparator);
15616 final long curRealtime = SystemClock.elapsedRealtime();
15617 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15618 final long curUptime = SystemClock.uptimeMillis();
15619 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15621 for (int i=list.size()-1; i>=0; i--) {
15622 ProcessRecord r = list.get(i).first;
15623 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15625 switch (r.setSchedGroup) {
15626 case ProcessList.SCHED_GROUP_BACKGROUND:
15629 case ProcessList.SCHED_GROUP_DEFAULT:
15632 case ProcessList.SCHED_GROUP_TOP_APP:
15640 if (r.foregroundActivities) {
15642 } else if (r.foregroundServices) {
15647 String procState = ProcessList.makeProcStateString(r.curProcState);
15649 pw.print(r.persistent ? persistentLabel : normalLabel);
15651 int num = (origList.size()-1)-list.get(i).second;
15652 if (num < 10) pw.print(' ');
15657 pw.print(schedGroup);
15659 pw.print(foreground);
15661 pw.print(procState);
15663 if (r.trimMemoryLevel < 10) pw.print(' ');
15664 pw.print(r.trimMemoryLevel);
15666 pw.print(r.toShortString());
15668 pw.print(r.adjType);
15670 if (r.adjSource != null || r.adjTarget != null) {
15673 if (r.adjTarget instanceof ComponentName) {
15674 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15675 } else if (r.adjTarget != null) {
15676 pw.print(r.adjTarget.toString());
15678 pw.print("{null}");
15681 if (r.adjSource instanceof ProcessRecord) {
15683 pw.print(((ProcessRecord)r.adjSource).toShortString());
15685 } else if (r.adjSource != null) {
15686 pw.println(r.adjSource.toString());
15688 pw.println("{null}");
15694 pw.print("oom: max="); pw.print(r.maxAdj);
15695 pw.print(" curRaw="); pw.print(r.curRawAdj);
15696 pw.print(" setRaw="); pw.print(r.setRawAdj);
15697 pw.print(" cur="); pw.print(r.curAdj);
15698 pw.print(" set="); pw.println(r.setAdj);
15701 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15702 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15703 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15704 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15705 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15709 pw.print("cached="); pw.print(r.cached);
15710 pw.print(" empty="); pw.print(r.empty);
15711 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15713 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15714 if (r.lastWakeTime != 0) {
15716 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15717 synchronized (stats) {
15718 wtime = stats.getProcessWakeTime(r.info.uid,
15719 r.pid, curRealtime);
15721 long timeUsed = wtime - r.lastWakeTime;
15724 pw.print("keep awake over ");
15725 TimeUtils.formatDuration(realtimeSince, pw);
15726 pw.print(" used ");
15727 TimeUtils.formatDuration(timeUsed, pw);
15729 pw.print((timeUsed*100)/realtimeSince);
15732 if (r.lastCpuTime != 0) {
15733 long timeUsed = r.curCpuTime - r.lastCpuTime;
15736 pw.print("run cpu over ");
15737 TimeUtils.formatDuration(uptimeSince, pw);
15738 pw.print(" used ");
15739 TimeUtils.formatDuration(timeUsed, pw);
15741 pw.print((timeUsed*100)/uptimeSince);
15750 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15752 ArrayList<ProcessRecord> procs;
15753 synchronized (this) {
15754 if (args != null && args.length > start
15755 && args[start].charAt(0) != '-') {
15756 procs = new ArrayList<ProcessRecord>();
15759 pid = Integer.parseInt(args[start]);
15760 } catch (NumberFormatException e) {
15762 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15763 ProcessRecord proc = mLruProcesses.get(i);
15764 if (proc.pid == pid) {
15766 } else if (allPkgs && proc.pkgList != null
15767 && proc.pkgList.containsKey(args[start])) {
15769 } else if (proc.processName.equals(args[start])) {
15773 if (procs.size() <= 0) {
15777 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15783 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15784 PrintWriter pw, String[] args) {
15785 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15786 if (procs == null) {
15787 pw.println("No process found for: " + args[0]);
15791 long uptime = SystemClock.uptimeMillis();
15792 long realtime = SystemClock.elapsedRealtime();
15793 pw.println("Applications Graphics Acceleration Info:");
15794 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15796 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15797 ProcessRecord r = procs.get(i);
15798 if (r.thread != null) {
15799 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15802 TransferPipe tp = new TransferPipe();
15804 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15809 } catch (IOException e) {
15810 pw.println("Failure while dumping the app: " + r);
15812 } catch (RemoteException e) {
15813 pw.println("Got a RemoteException while dumping the app " + r);
15820 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15821 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15822 if (procs == null) {
15823 pw.println("No process found for: " + args[0]);
15827 pw.println("Applications Database Info:");
15829 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15830 ProcessRecord r = procs.get(i);
15831 if (r.thread != null) {
15832 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15835 TransferPipe tp = new TransferPipe();
15837 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15842 } catch (IOException e) {
15843 pw.println("Failure while dumping the app: " + r);
15845 } catch (RemoteException e) {
15846 pw.println("Got a RemoteException while dumping the app " + r);
15853 final static class MemItem {
15854 final boolean isProc;
15855 final String label;
15856 final String shortLabel;
15858 final long swapPss;
15860 final boolean hasActivities;
15861 ArrayList<MemItem> subitems;
15863 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15864 boolean _hasActivities) {
15867 shortLabel = _shortLabel;
15869 swapPss = _swapPss;
15871 hasActivities = _hasActivities;
15874 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15877 shortLabel = _shortLabel;
15879 swapPss = _swapPss;
15881 hasActivities = false;
15885 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15886 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15887 if (sort && !isCompact) {
15888 Collections.sort(items, new Comparator<MemItem>() {
15890 public int compare(MemItem lhs, MemItem rhs) {
15891 if (lhs.pss < rhs.pss) {
15893 } else if (lhs.pss > rhs.pss) {
15901 for (int i=0; i<items.size(); i++) {
15902 MemItem mi = items.get(i);
15905 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15906 mi.label, stringifyKBSize(mi.swapPss));
15908 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15910 } else if (mi.isProc) {
15911 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15912 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15913 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15914 pw.println(mi.hasActivities ? ",a" : ",e");
15916 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15917 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15919 if (mi.subitems != null) {
15920 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15921 true, isCompact, dumpSwapPss);
15926 // These are in KB.
15927 static final long[] DUMP_MEM_BUCKETS = new long[] {
15928 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15929 120*1024, 160*1024, 200*1024,
15930 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15931 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15934 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15935 boolean stackLike) {
15936 int start = label.lastIndexOf('.');
15937 if (start >= 0) start++;
15939 int end = label.length();
15940 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15941 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15942 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15943 out.append(bucket);
15944 out.append(stackLike ? "MB." : "MB ");
15945 out.append(label, start, end);
15949 out.append(memKB/1024);
15950 out.append(stackLike ? "MB." : "MB ");
15951 out.append(label, start, end);
15954 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15955 ProcessList.NATIVE_ADJ,
15956 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15957 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15958 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15959 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15960 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15961 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15963 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15965 "System", "Persistent", "Persistent Service", "Foreground",
15966 "Visible", "Perceptible",
15967 "Heavy Weight", "Backup",
15968 "A Services", "Home",
15969 "Previous", "B Services", "Cached"
15971 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15973 "sys", "pers", "persvc", "fore",
15976 "servicea", "home",
15977 "prev", "serviceb", "cached"
15980 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15981 long realtime, boolean isCheckinRequest, boolean isCompact) {
15983 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15985 if (isCheckinRequest || isCompact) {
15986 // short checkin version
15987 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15989 pw.println("Applications Memory Usage (in Kilobytes):");
15990 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15994 private static final int KSM_SHARED = 0;
15995 private static final int KSM_SHARING = 1;
15996 private static final int KSM_UNSHARED = 2;
15997 private static final int KSM_VOLATILE = 3;
15999 private final long[] getKsmInfo() {
16000 long[] longOut = new long[4];
16001 final int[] SINGLE_LONG_FORMAT = new int[] {
16002 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16004 long[] longTmp = new long[1];
16005 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16006 SINGLE_LONG_FORMAT, null, longTmp, null);
16007 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16009 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16010 SINGLE_LONG_FORMAT, null, longTmp, null);
16011 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16013 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16014 SINGLE_LONG_FORMAT, null, longTmp, null);
16015 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16017 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16018 SINGLE_LONG_FORMAT, null, longTmp, null);
16019 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16023 private static String stringifySize(long size, int order) {
16024 Locale locale = Locale.US;
16027 return String.format(locale, "%,13d", size);
16029 return String.format(locale, "%,9dK", size / 1024);
16031 return String.format(locale, "%,5dM", size / 1024 / 1024);
16032 case 1024 * 1024 * 1024:
16033 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16035 throw new IllegalArgumentException("Invalid size order");
16039 private static String stringifyKBSize(long size) {
16040 return stringifySize(size * 1024, 1024);
16043 // Update this version number in case you change the 'compact' format
16044 private static final int MEMINFO_COMPACT_VERSION = 1;
16046 final void dumpApplicationMemoryUsage(FileDescriptor fd,
16047 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16048 boolean dumpDetails = false;
16049 boolean dumpFullDetails = false;
16050 boolean dumpDalvik = false;
16051 boolean dumpSummaryOnly = false;
16052 boolean dumpUnreachable = false;
16053 boolean oomOnly = false;
16054 boolean isCompact = false;
16055 boolean localOnly = false;
16056 boolean packages = false;
16057 boolean isCheckinRequest = false;
16058 boolean dumpSwapPss = false;
16061 while (opti < args.length) {
16062 String opt = args[opti];
16063 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16067 if ("-a".equals(opt)) {
16068 dumpDetails = true;
16069 dumpFullDetails = true;
16071 dumpSwapPss = true;
16072 } else if ("-d".equals(opt)) {
16074 } else if ("-c".equals(opt)) {
16076 } else if ("-s".equals(opt)) {
16077 dumpDetails = true;
16078 dumpSummaryOnly = true;
16079 } else if ("-S".equals(opt)) {
16080 dumpSwapPss = true;
16081 } else if ("--unreachable".equals(opt)) {
16082 dumpUnreachable = true;
16083 } else if ("--oom".equals(opt)) {
16085 } else if ("--local".equals(opt)) {
16087 } else if ("--package".equals(opt)) {
16089 } else if ("--checkin".equals(opt)) {
16090 isCheckinRequest = true;
16092 } else if ("-h".equals(opt)) {
16093 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16094 pw.println(" -a: include all available information for each process.");
16095 pw.println(" -d: include dalvik details.");
16096 pw.println(" -c: dump in a compact machine-parseable representation.");
16097 pw.println(" -s: dump only summary of application memory usage.");
16098 pw.println(" -S: dump also SwapPss.");
16099 pw.println(" --oom: only show processes organized by oom adj.");
16100 pw.println(" --local: only collect details locally, don't call process.");
16101 pw.println(" --package: interpret process arg as package, dumping all");
16102 pw.println(" processes that have loaded that package.");
16103 pw.println(" --checkin: dump data for a checkin");
16104 pw.println("If [process] is specified it can be the name or ");
16105 pw.println("pid of a specific process to dump.");
16108 pw.println("Unknown argument: " + opt + "; use -h for help");
16112 long uptime = SystemClock.uptimeMillis();
16113 long realtime = SystemClock.elapsedRealtime();
16114 final long[] tmpLong = new long[1];
16116 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16117 if (procs == null) {
16118 // No Java processes. Maybe they want to print a native process.
16119 if (args != null && args.length > opti
16120 && args[opti].charAt(0) != '-') {
16121 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16122 = new ArrayList<ProcessCpuTracker.Stats>();
16123 updateCpuStatsNow();
16126 findPid = Integer.parseInt(args[opti]);
16127 } catch (NumberFormatException e) {
16129 synchronized (mProcessCpuTracker) {
16130 final int N = mProcessCpuTracker.countStats();
16131 for (int i=0; i<N; i++) {
16132 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16133 if (st.pid == findPid || (st.baseName != null
16134 && st.baseName.equals(args[opti]))) {
16135 nativeProcs.add(st);
16139 if (nativeProcs.size() > 0) {
16140 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16142 Debug.MemoryInfo mi = null;
16143 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16144 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16145 final int pid = r.pid;
16146 if (!isCheckinRequest && dumpDetails) {
16147 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16150 mi = new Debug.MemoryInfo();
16152 if (dumpDetails || (!brief && !oomOnly)) {
16153 Debug.getMemoryInfo(pid, mi);
16155 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16156 mi.dalvikPrivateDirty = (int)tmpLong[0];
16158 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16159 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16160 if (isCheckinRequest) {
16167 pw.println("No process found for: " + args[opti]);
16171 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16172 dumpDetails = true;
16175 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16177 String[] innerArgs = new String[args.length-opti];
16178 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16180 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16181 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16182 long nativePss = 0;
16183 long nativeSwapPss = 0;
16184 long dalvikPss = 0;
16185 long dalvikSwapPss = 0;
16186 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16188 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16191 long otherSwapPss = 0;
16192 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16193 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16195 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16196 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16197 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16198 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16201 long totalSwapPss = 0;
16202 long cachedPss = 0;
16203 long cachedSwapPss = 0;
16204 boolean hasSwapPss = false;
16206 Debug.MemoryInfo mi = null;
16207 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16208 final ProcessRecord r = procs.get(i);
16209 final IApplicationThread thread;
16212 final boolean hasActivities;
16213 synchronized (this) {
16216 oomAdj = r.getSetAdjWithServices();
16217 hasActivities = r.activities.size() > 0;
16219 if (thread != null) {
16220 if (!isCheckinRequest && dumpDetails) {
16221 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16224 mi = new Debug.MemoryInfo();
16226 if (dumpDetails || (!brief && !oomOnly)) {
16227 Debug.getMemoryInfo(pid, mi);
16228 hasSwapPss = mi.hasSwappedOutPss;
16230 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16231 mi.dalvikPrivateDirty = (int)tmpLong[0];
16235 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16236 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16237 if (isCheckinRequest) {
16243 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16244 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16245 } catch (RemoteException e) {
16246 if (!isCheckinRequest) {
16247 pw.println("Got RemoteException!");
16254 final long myTotalPss = mi.getTotalPss();
16255 final long myTotalUss = mi.getTotalUss();
16256 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16258 synchronized (this) {
16259 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16260 // Record this for posterity if the process has been stable.
16261 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16265 if (!isCheckinRequest && mi != null) {
16266 totalPss += myTotalPss;
16267 totalSwapPss += myTotalSwapPss;
16268 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16269 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16270 myTotalSwapPss, pid, hasActivities);
16271 procMems.add(pssItem);
16272 procMemsMap.put(pid, pssItem);
16274 nativePss += mi.nativePss;
16275 nativeSwapPss += mi.nativeSwappedOutPss;
16276 dalvikPss += mi.dalvikPss;
16277 dalvikSwapPss += mi.dalvikSwappedOutPss;
16278 for (int j=0; j<dalvikSubitemPss.length; j++) {
16279 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16280 dalvikSubitemSwapPss[j] +=
16281 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16283 otherPss += mi.otherPss;
16284 otherSwapPss += mi.otherSwappedOutPss;
16285 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16286 long mem = mi.getOtherPss(j);
16289 mem = mi.getOtherSwappedOutPss(j);
16290 miscSwapPss[j] += mem;
16291 otherSwapPss -= mem;
16294 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16295 cachedPss += myTotalPss;
16296 cachedSwapPss += myTotalSwapPss;
16299 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16300 if (oomIndex == (oomPss.length - 1)
16301 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16302 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16303 oomPss[oomIndex] += myTotalPss;
16304 oomSwapPss[oomIndex] += myTotalSwapPss;
16305 if (oomProcs[oomIndex] == null) {
16306 oomProcs[oomIndex] = new ArrayList<MemItem>();
16308 oomProcs[oomIndex].add(pssItem);
16316 long nativeProcTotalPss = 0;
16318 if (!isCheckinRequest && procs.size() > 1 && !packages) {
16319 // If we are showing aggregations, also look for native processes to
16320 // include so that our aggregations are more accurate.
16321 updateCpuStatsNow();
16323 synchronized (mProcessCpuTracker) {
16324 final int N = mProcessCpuTracker.countStats();
16325 for (int i=0; i<N; i++) {
16326 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16327 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16329 mi = new Debug.MemoryInfo();
16331 if (!brief && !oomOnly) {
16332 Debug.getMemoryInfo(st.pid, mi);
16334 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16335 mi.nativePrivateDirty = (int)tmpLong[0];
16338 final long myTotalPss = mi.getTotalPss();
16339 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16340 totalPss += myTotalPss;
16341 nativeProcTotalPss += myTotalPss;
16343 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16344 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16345 procMems.add(pssItem);
16347 nativePss += mi.nativePss;
16348 nativeSwapPss += mi.nativeSwappedOutPss;
16349 dalvikPss += mi.dalvikPss;
16350 dalvikSwapPss += mi.dalvikSwappedOutPss;
16351 for (int j=0; j<dalvikSubitemPss.length; j++) {
16352 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16353 dalvikSubitemSwapPss[j] +=
16354 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16356 otherPss += mi.otherPss;
16357 otherSwapPss += mi.otherSwappedOutPss;
16358 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16359 long mem = mi.getOtherPss(j);
16362 mem = mi.getOtherSwappedOutPss(j);
16363 miscSwapPss[j] += mem;
16364 otherSwapPss -= mem;
16366 oomPss[0] += myTotalPss;
16367 oomSwapPss[0] += myTotalSwapPss;
16368 if (oomProcs[0] == null) {
16369 oomProcs[0] = new ArrayList<MemItem>();
16371 oomProcs[0].add(pssItem);
16376 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16378 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16379 final MemItem dalvikItem =
16380 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16381 if (dalvikSubitemPss.length > 0) {
16382 dalvikItem.subitems = new ArrayList<MemItem>();
16383 for (int j=0; j<dalvikSubitemPss.length; j++) {
16384 final String name = Debug.MemoryInfo.getOtherLabel(
16385 Debug.MemoryInfo.NUM_OTHER_STATS + j);
16386 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16387 dalvikSubitemSwapPss[j], j));
16390 catMems.add(dalvikItem);
16391 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16392 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16393 String label = Debug.MemoryInfo.getOtherLabel(j);
16394 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16397 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16398 for (int j=0; j<oomPss.length; j++) {
16399 if (oomPss[j] != 0) {
16400 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16401 : DUMP_MEM_OOM_LABEL[j];
16402 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16403 DUMP_MEM_OOM_ADJ[j]);
16404 item.subitems = oomProcs[j];
16409 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16410 if (!brief && !oomOnly && !isCompact) {
16412 pw.println("Total PSS by process:");
16413 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
16417 pw.println("Total PSS by OOM adjustment:");
16419 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
16420 if (!brief && !oomOnly) {
16421 PrintWriter out = categoryPw != null ? categoryPw : pw;
16424 out.println("Total PSS by category:");
16426 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
16431 MemInfoReader memInfo = new MemInfoReader();
16432 memInfo.readMemInfo();
16433 if (nativeProcTotalPss > 0) {
16434 synchronized (this) {
16435 final long cachedKb = memInfo.getCachedSizeKb();
16436 final long freeKb = memInfo.getFreeSizeKb();
16437 final long zramKb = memInfo.getZramTotalSizeKb();
16438 final long kernelKb = memInfo.getKernelUsedSizeKb();
16439 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16440 kernelKb*1024, nativeProcTotalPss*1024);
16441 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16442 nativeProcTotalPss);
16447 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16448 pw.print(" (status ");
16449 switch (mLastMemoryLevel) {
16450 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16451 pw.println("normal)");
16453 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16454 pw.println("moderate)");
16456 case ProcessStats.ADJ_MEM_FACTOR_LOW:
16457 pw.println("low)");
16459 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16460 pw.println("critical)");
16463 pw.print(mLastMemoryLevel);
16467 pw.print(" Free RAM: ");
16468 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16469 + memInfo.getFreeSizeKb()));
16471 pw.print(stringifyKBSize(cachedPss));
16472 pw.print(" cached pss + ");
16473 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16474 pw.print(" cached kernel + ");
16475 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16476 pw.println(" free)");
16478 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16479 pw.print(cachedPss + memInfo.getCachedSizeKb()
16480 + memInfo.getFreeSizeKb()); pw.print(",");
16481 pw.println(totalPss - cachedPss);
16484 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16485 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16486 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16488 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16489 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16490 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16491 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16492 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16494 pw.print("lostram,"); pw.println(lostRAM);
16497 if (memInfo.getZramTotalSizeKb() != 0) {
16499 pw.print(" ZRAM: ");
16500 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16501 pw.print(" physical used for ");
16502 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16503 - memInfo.getSwapFreeSizeKb()));
16504 pw.print(" in swap (");
16505 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16506 pw.println(" total swap)");
16508 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16509 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16510 pw.println(memInfo.getSwapFreeSizeKb());
16513 final long[] ksm = getKsmInfo();
16515 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16516 || ksm[KSM_VOLATILE] != 0) {
16517 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16518 pw.print(" saved from shared ");
16519 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16520 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16521 pw.print(" unshared; ");
16522 pw.print(stringifyKBSize(
16523 ksm[KSM_VOLATILE])); pw.println(" volatile");
16525 pw.print(" Tuning: ");
16526 pw.print(ActivityManager.staticGetMemoryClass());
16527 pw.print(" (large ");
16528 pw.print(ActivityManager.staticGetLargeMemoryClass());
16529 pw.print("), oom ");
16530 pw.print(stringifySize(
16531 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16532 pw.print(", restore limit ");
16533 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16534 if (ActivityManager.isLowRamDeviceStatic()) {
16535 pw.print(" (low-ram)");
16537 if (ActivityManager.isHighEndGfx()) {
16538 pw.print(" (high-end-gfx)");
16542 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16543 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16544 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16545 pw.print("tuning,");
16546 pw.print(ActivityManager.staticGetMemoryClass());
16548 pw.print(ActivityManager.staticGetLargeMemoryClass());
16550 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16551 if (ActivityManager.isLowRamDeviceStatic()) {
16552 pw.print(",low-ram");
16554 if (ActivityManager.isHighEndGfx()) {
16555 pw.print(",high-end-gfx");
16563 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16564 long memtrack, String name) {
16566 sb.append(ProcessList.makeOomAdjString(oomAdj));
16568 sb.append(ProcessList.makeProcStateString(procState));
16570 ProcessList.appendRamKb(sb, pss);
16573 if (memtrack > 0) {
16575 sb.append(stringifyKBSize(memtrack));
16576 sb.append(" memtrack)");
16580 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16581 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16582 sb.append(" (pid ");
16585 sb.append(mi.adjType);
16587 if (mi.adjReason != null) {
16589 sb.append(mi.adjReason);
16594 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16595 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16596 for (int i=0, N=memInfos.size(); i<N; i++) {
16597 ProcessMemInfo mi = memInfos.get(i);
16598 infoMap.put(mi.pid, mi);
16600 updateCpuStatsNow();
16601 long[] memtrackTmp = new long[1];
16602 final List<ProcessCpuTracker.Stats> stats;
16603 // Get a list of Stats that have vsize > 0
16604 synchronized (mProcessCpuTracker) {
16605 stats = mProcessCpuTracker.getStats((st) -> {
16606 return st.vsize > 0;
16609 final int statsCount = stats.size();
16610 for (int i = 0; i < statsCount; i++) {
16611 ProcessCpuTracker.Stats st = stats.get(i);
16612 long pss = Debug.getPss(st.pid, null, memtrackTmp);
16614 if (infoMap.indexOfKey(st.pid) < 0) {
16615 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16616 ProcessList.NATIVE_ADJ, -1, "native", null);
16618 mi.memtrack = memtrackTmp[0];
16625 long totalMemtrack = 0;
16626 for (int i=0, N=memInfos.size(); i<N; i++) {
16627 ProcessMemInfo mi = memInfos.get(i);
16629 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16630 mi.memtrack = memtrackTmp[0];
16632 totalPss += mi.pss;
16633 totalMemtrack += mi.memtrack;
16635 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16636 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16637 if (lhs.oomAdj != rhs.oomAdj) {
16638 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16640 if (lhs.pss != rhs.pss) {
16641 return lhs.pss < rhs.pss ? 1 : -1;
16647 StringBuilder tag = new StringBuilder(128);
16648 StringBuilder stack = new StringBuilder(128);
16649 tag.append("Low on memory -- ");
16650 appendMemBucket(tag, totalPss, "total", false);
16651 appendMemBucket(stack, totalPss, "total", true);
16653 StringBuilder fullNativeBuilder = new StringBuilder(1024);
16654 StringBuilder shortNativeBuilder = new StringBuilder(1024);
16655 StringBuilder fullJavaBuilder = new StringBuilder(1024);
16657 boolean firstLine = true;
16658 int lastOomAdj = Integer.MIN_VALUE;
16659 long extraNativeRam = 0;
16660 long extraNativeMemtrack = 0;
16661 long cachedPss = 0;
16662 for (int i=0, N=memInfos.size(); i<N; i++) {
16663 ProcessMemInfo mi = memInfos.get(i);
16665 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16666 cachedPss += mi.pss;
16669 if (mi.oomAdj != ProcessList.NATIVE_ADJ
16670 && (mi.oomAdj < ProcessList.SERVICE_ADJ
16671 || mi.oomAdj == ProcessList.HOME_APP_ADJ
16672 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16673 if (lastOomAdj != mi.oomAdj) {
16674 lastOomAdj = mi.oomAdj;
16675 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16678 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16683 stack.append("\n\t at ");
16691 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16692 appendMemBucket(tag, mi.pss, mi.name, false);
16694 appendMemBucket(stack, mi.pss, mi.name, true);
16695 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16696 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16698 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16699 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16700 stack.append(DUMP_MEM_OOM_LABEL[k]);
16702 stack.append(DUMP_MEM_OOM_ADJ[k]);
16709 appendMemInfo(fullNativeBuilder, mi);
16710 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16711 // The short form only has native processes that are >= 512K.
16712 if (mi.pss >= 512) {
16713 appendMemInfo(shortNativeBuilder, mi);
16715 extraNativeRam += mi.pss;
16716 extraNativeMemtrack += mi.memtrack;
16719 // Short form has all other details, but if we have collected RAM
16720 // from smaller native processes let's dump a summary of that.
16721 if (extraNativeRam > 0) {
16722 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16723 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16724 shortNativeBuilder.append('\n');
16725 extraNativeRam = 0;
16727 appendMemInfo(fullJavaBuilder, mi);
16731 fullJavaBuilder.append(" ");
16732 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16733 fullJavaBuilder.append(": TOTAL");
16734 if (totalMemtrack > 0) {
16735 fullJavaBuilder.append(" (");
16736 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16737 fullJavaBuilder.append(" memtrack)");
16740 fullJavaBuilder.append("\n");
16742 MemInfoReader memInfo = new MemInfoReader();
16743 memInfo.readMemInfo();
16744 final long[] infos = memInfo.getRawInfo();
16746 StringBuilder memInfoBuilder = new StringBuilder(1024);
16747 Debug.getMemInfo(infos);
16748 memInfoBuilder.append(" MemInfo: ");
16749 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16750 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16751 memInfoBuilder.append(stringifyKBSize(
16752 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16753 memInfoBuilder.append(stringifyKBSize(
16754 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16755 memInfoBuilder.append(stringifyKBSize(
16756 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16757 memInfoBuilder.append(" ");
16758 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16759 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16760 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16761 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16762 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16763 memInfoBuilder.append(" ZRAM: ");
16764 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16765 memInfoBuilder.append(" RAM, ");
16766 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16767 memInfoBuilder.append(" swap total, ");
16768 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16769 memInfoBuilder.append(" swap free\n");
16771 final long[] ksm = getKsmInfo();
16772 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16773 || ksm[KSM_VOLATILE] != 0) {
16774 memInfoBuilder.append(" KSM: ");
16775 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16776 memInfoBuilder.append(" saved from shared ");
16777 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16778 memInfoBuilder.append("\n ");
16779 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16780 memInfoBuilder.append(" unshared; ");
16781 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16782 memInfoBuilder.append(" volatile\n");
16784 memInfoBuilder.append(" Free RAM: ");
16785 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16786 + memInfo.getFreeSizeKb()));
16787 memInfoBuilder.append("\n");
16788 memInfoBuilder.append(" Used RAM: ");
16789 memInfoBuilder.append(stringifyKBSize(
16790 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16791 memInfoBuilder.append("\n");
16792 memInfoBuilder.append(" Lost RAM: ");
16793 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16794 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16795 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16796 memInfoBuilder.append("\n");
16797 Slog.i(TAG, "Low on memory:");
16798 Slog.i(TAG, shortNativeBuilder.toString());
16799 Slog.i(TAG, fullJavaBuilder.toString());
16800 Slog.i(TAG, memInfoBuilder.toString());
16802 StringBuilder dropBuilder = new StringBuilder(1024);
16804 StringWriter oomSw = new StringWriter();
16805 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16806 StringWriter catSw = new StringWriter();
16807 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16808 String[] emptyArgs = new String[] { };
16809 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16811 String oomString = oomSw.toString();
16813 dropBuilder.append("Low on memory:");
16814 dropBuilder.append(stack);
16815 dropBuilder.append('\n');
16816 dropBuilder.append(fullNativeBuilder);
16817 dropBuilder.append(fullJavaBuilder);
16818 dropBuilder.append('\n');
16819 dropBuilder.append(memInfoBuilder);
16820 dropBuilder.append('\n');
16822 dropBuilder.append(oomString);
16823 dropBuilder.append('\n');
16825 StringWriter catSw = new StringWriter();
16826 synchronized (ActivityManagerService.this) {
16827 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16828 String[] emptyArgs = new String[] { };
16830 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16832 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16833 false, null).dumpLocked();
16835 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16838 dropBuilder.append(catSw.toString());
16839 addErrorToDropBox("lowmem", null, "system_server", null,
16840 null, tag.toString(), dropBuilder.toString(), null, null);
16841 //Slog.i(TAG, "Sent to dropbox:");
16842 //Slog.i(TAG, dropBuilder.toString());
16843 synchronized (ActivityManagerService.this) {
16844 long now = SystemClock.uptimeMillis();
16845 if (mLastMemUsageReportTime < now) {
16846 mLastMemUsageReportTime = now;
16852 * Searches array of arguments for the specified string
16853 * @param args array of argument strings
16854 * @param value value to search for
16855 * @return true if the value is contained in the array
16857 private static boolean scanArgs(String[] args, String value) {
16858 if (args != null) {
16859 for (String arg : args) {
16860 if (value.equals(arg)) {
16868 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16869 ContentProviderRecord cpr, boolean always) {
16870 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16872 if (!inLaunching || always) {
16873 synchronized (cpr) {
16874 cpr.launchingApp = null;
16877 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16878 String names[] = cpr.info.authority.split(";");
16879 for (int j = 0; j < names.length; j++) {
16880 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16884 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16885 ContentProviderConnection conn = cpr.connections.get(i);
16886 if (conn.waiting) {
16887 // If this connection is waiting for the provider, then we don't
16888 // need to mess with its process unless we are always removing
16889 // or for some reason the provider is not currently launching.
16890 if (inLaunching && !always) {
16894 ProcessRecord capp = conn.client;
16896 if (conn.stableCount > 0) {
16897 if (!capp.persistent && capp.thread != null
16899 && capp.pid != MY_PID) {
16900 capp.kill("depends on provider "
16901 + cpr.name.flattenToShortString()
16902 + " in dying proc " + (proc != null ? proc.processName : "??")
16903 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16905 } else if (capp.thread != null && conn.provider.provider != null) {
16907 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16908 } catch (RemoteException e) {
16910 // In the protocol here, we don't expect the client to correctly
16911 // clean up this connection, we'll just remove it.
16912 cpr.connections.remove(i);
16913 if (conn.client.conProviders.remove(conn)) {
16914 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16919 if (inLaunching && always) {
16920 mLaunchingProviders.remove(cpr);
16922 return inLaunching;
16926 * Main code for cleaning up a process when it has gone away. This is
16927 * called both as a result of the process dying, or directly when stopping
16928 * a process when running in single process mode.
16930 * @return Returns true if the given process has been restarted, so the
16931 * app that was passed in must remain on the process lists.
16933 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16934 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16935 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16937 removeLruProcessLocked(app);
16938 ProcessList.remove(app.pid);
16941 mProcessesToGc.remove(app);
16942 mPendingPssProcesses.remove(app);
16944 // Dismiss any open dialogs.
16945 if (app.crashDialog != null && !app.forceCrashReport) {
16946 app.crashDialog.dismiss();
16947 app.crashDialog = null;
16949 if (app.anrDialog != null) {
16950 app.anrDialog.dismiss();
16951 app.anrDialog = null;
16953 if (app.waitDialog != null) {
16954 app.waitDialog.dismiss();
16955 app.waitDialog = null;
16958 app.crashing = false;
16959 app.notResponding = false;
16961 app.resetPackageList(mProcessStats);
16962 app.unlinkDeathRecipient();
16963 app.makeInactive(mProcessStats);
16964 app.waitingToKill = null;
16965 app.forcingToForeground = null;
16966 updateProcessForegroundLocked(app, false, false);
16967 app.foregroundActivities = false;
16968 app.hasShownUi = false;
16969 app.treatLikeActivity = false;
16970 app.hasAboveClient = false;
16971 app.hasClientActivities = false;
16973 mServices.killServicesLocked(app, allowRestart);
16975 boolean restart = false;
16977 // Remove published content providers.
16978 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16979 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16980 final boolean always = app.bad || !allowRestart;
16981 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16982 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16983 // We left the provider in the launching list, need to
16988 cpr.provider = null;
16991 app.pubProviders.clear();
16993 // Take care of any launching providers waiting for this process.
16994 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16998 // Unregister from connected content providers.
16999 if (!app.conProviders.isEmpty()) {
17000 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17001 ContentProviderConnection conn = app.conProviders.get(i);
17002 conn.provider.connections.remove(conn);
17003 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17004 conn.provider.name);
17006 app.conProviders.clear();
17009 // At this point there may be remaining entries in mLaunchingProviders
17010 // where we were the only one waiting, so they are no longer of use.
17011 // Look for these and clean up if found.
17012 // XXX Commented out for now. Trying to figure out a way to reproduce
17013 // the actual situation to identify what is actually going on.
17015 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17016 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17017 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17018 synchronized (cpr) {
17019 cpr.launchingApp = null;
17026 skipCurrentReceiverLocked(app);
17028 // Unregister any receivers.
17029 for (int i = app.receivers.size() - 1; i >= 0; i--) {
17030 removeReceiverLocked(app.receivers.valueAt(i));
17032 app.receivers.clear();
17034 // If the app is undergoing backup, tell the backup manager about it
17035 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17036 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17037 + mBackupTarget.appInfo + " died during backup");
17039 IBackupManager bm = IBackupManager.Stub.asInterface(
17040 ServiceManager.getService(Context.BACKUP_SERVICE));
17041 bm.agentDisconnected(app.info.packageName);
17042 } catch (RemoteException e) {
17043 // can't happen; backup manager is local
17047 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17048 ProcessChangeItem item = mPendingProcessChanges.get(i);
17049 if (item.pid == app.pid) {
17050 mPendingProcessChanges.remove(i);
17051 mAvailProcessChanges.add(item);
17054 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17055 null).sendToTarget();
17057 // If the caller is restarting this app, then leave it in its
17058 // current lists and let the caller take care of it.
17063 if (!app.persistent || app.isolated) {
17064 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17065 "Removing non-persistent process during cleanup: " + app);
17066 if (!replacingPid) {
17067 removeProcessNameLocked(app.processName, app.uid, app);
17069 if (mHeavyWeightProcess == app) {
17070 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17071 mHeavyWeightProcess.userId, 0));
17072 mHeavyWeightProcess = null;
17074 } else if (!app.removed) {
17075 // This app is persistent, so we need to keep its record around.
17076 // If it is not already on the pending app list, add it there
17077 // and start a new process for it.
17078 if (mPersistentStartingProcesses.indexOf(app) < 0) {
17079 mPersistentStartingProcesses.add(app);
17083 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17084 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17085 mProcessesOnHold.remove(app);
17087 if (app == mHomeProcess) {
17088 mHomeProcess = null;
17090 if (app == mPreviousProcess) {
17091 mPreviousProcess = null;
17094 if (restart && !app.isolated) {
17095 // We have components that still need to be running in the
17096 // process, so re-launch it.
17098 ProcessList.remove(app.pid);
17100 addProcessNameLocked(app);
17101 startProcessLocked(app, "restart", app.processName);
17103 } else if (app.pid > 0 && app.pid != MY_PID) {
17106 synchronized (mPidsSelfLocked) {
17107 mPidsSelfLocked.remove(app.pid);
17108 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17110 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17111 if (app.isolated) {
17112 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17119 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17120 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17121 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17122 if (cpr.launchingApp == app) {
17129 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17130 // Look through the content providers we are waiting to have launched,
17131 // and if any run in this process then either schedule a restart of
17132 // the process or kill the client waiting for it if this process has
17134 boolean restart = false;
17135 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17136 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17137 if (cpr.launchingApp == app) {
17138 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17141 removeDyingProviderLocked(app, cpr, true);
17148 // =========================================================
17150 // =========================================================
17153 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17155 enforceNotIsolatedCaller("getServices");
17156 synchronized (this) {
17157 return mServices.getRunningServiceInfoLocked(maxNum, flags);
17162 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17163 enforceNotIsolatedCaller("getRunningServiceControlPanel");
17164 synchronized (this) {
17165 return mServices.getRunningServiceControlPanelLocked(name);
17170 public ComponentName startService(IApplicationThread caller, Intent service,
17171 String resolvedType, String callingPackage, int userId)
17172 throws TransactionTooLargeException {
17173 enforceNotIsolatedCaller("startService");
17174 // Refuse possible leaked file descriptors
17175 if (service != null && service.hasFileDescriptors() == true) {
17176 throw new IllegalArgumentException("File descriptors passed in Intent");
17179 if (callingPackage == null) {
17180 throw new IllegalArgumentException("callingPackage cannot be null");
17183 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17184 "startService: " + service + " type=" + resolvedType);
17185 synchronized(this) {
17186 final int callingPid = Binder.getCallingPid();
17187 final int callingUid = Binder.getCallingUid();
17188 final long origId = Binder.clearCallingIdentity();
17189 ComponentName res = mServices.startServiceLocked(caller, service,
17190 resolvedType, callingPid, callingUid, callingPackage, userId);
17191 Binder.restoreCallingIdentity(origId);
17196 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17197 String callingPackage, int userId)
17198 throws TransactionTooLargeException {
17199 synchronized(this) {
17200 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17201 "startServiceInPackage: " + service + " type=" + resolvedType);
17202 final long origId = Binder.clearCallingIdentity();
17203 ComponentName res = mServices.startServiceLocked(null, service,
17204 resolvedType, -1, uid, callingPackage, userId);
17205 Binder.restoreCallingIdentity(origId);
17211 public int stopService(IApplicationThread caller, Intent service,
17212 String resolvedType, int userId) {
17213 enforceNotIsolatedCaller("stopService");
17214 // Refuse possible leaked file descriptors
17215 if (service != null && service.hasFileDescriptors() == true) {
17216 throw new IllegalArgumentException("File descriptors passed in Intent");
17219 synchronized(this) {
17220 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17225 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17226 enforceNotIsolatedCaller("peekService");
17227 // Refuse possible leaked file descriptors
17228 if (service != null && service.hasFileDescriptors() == true) {
17229 throw new IllegalArgumentException("File descriptors passed in Intent");
17232 if (callingPackage == null) {
17233 throw new IllegalArgumentException("callingPackage cannot be null");
17236 synchronized(this) {
17237 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17242 public boolean stopServiceToken(ComponentName className, IBinder token,
17244 synchronized(this) {
17245 return mServices.stopServiceTokenLocked(className, token, startId);
17250 public void setServiceForeground(ComponentName className, IBinder token,
17251 int id, Notification notification, int flags) {
17252 synchronized(this) {
17253 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17258 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17259 boolean requireFull, String name, String callerPackage) {
17260 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17261 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17264 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17265 String className, int flags) {
17266 boolean result = false;
17267 // For apps that don't have pre-defined UIDs, check for permission
17268 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17269 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17270 if (ActivityManager.checkUidPermission(
17271 INTERACT_ACROSS_USERS,
17272 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17273 ComponentName comp = new ComponentName(aInfo.packageName, className);
17274 String msg = "Permission Denial: Component " + comp.flattenToShortString()
17275 + " requests FLAG_SINGLE_USER, but app does not hold "
17276 + INTERACT_ACROSS_USERS;
17278 throw new SecurityException(msg);
17280 // Permission passed
17283 } else if ("system".equals(componentProcessName)) {
17285 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17286 // Phone app and persistent apps are allowed to export singleuser providers.
17287 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17288 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17290 if (DEBUG_MU) Slog.v(TAG_MU,
17291 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17292 + Integer.toHexString(flags) + ") = " + result);
17297 * Checks to see if the caller is in the same app as the singleton
17298 * component, or the component is in a special app. It allows special apps
17299 * to export singleton components but prevents exporting singleton
17300 * components for regular apps.
17302 boolean isValidSingletonCall(int callingUid, int componentUid) {
17303 int componentAppId = UserHandle.getAppId(componentUid);
17304 return UserHandle.isSameApp(callingUid, componentUid)
17305 || componentAppId == Process.SYSTEM_UID
17306 || componentAppId == Process.PHONE_UID
17307 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17308 == PackageManager.PERMISSION_GRANTED;
17311 public int bindService(IApplicationThread caller, IBinder token, Intent service,
17312 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17313 int userId) throws TransactionTooLargeException {
17314 enforceNotIsolatedCaller("bindService");
17316 // Refuse possible leaked file descriptors
17317 if (service != null && service.hasFileDescriptors() == true) {
17318 throw new IllegalArgumentException("File descriptors passed in Intent");
17321 if (callingPackage == null) {
17322 throw new IllegalArgumentException("callingPackage cannot be null");
17325 synchronized(this) {
17326 return mServices.bindServiceLocked(caller, token, service,
17327 resolvedType, connection, flags, callingPackage, userId);
17331 public boolean unbindService(IServiceConnection connection) {
17332 synchronized (this) {
17333 return mServices.unbindServiceLocked(connection);
17337 public void publishService(IBinder token, Intent intent, IBinder service) {
17338 // Refuse possible leaked file descriptors
17339 if (intent != null && intent.hasFileDescriptors() == true) {
17340 throw new IllegalArgumentException("File descriptors passed in Intent");
17343 synchronized(this) {
17344 if (!(token instanceof ServiceRecord)) {
17345 throw new IllegalArgumentException("Invalid service token");
17347 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17351 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17352 // Refuse possible leaked file descriptors
17353 if (intent != null && intent.hasFileDescriptors() == true) {
17354 throw new IllegalArgumentException("File descriptors passed in Intent");
17357 synchronized(this) {
17358 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17362 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17363 synchronized(this) {
17364 if (!(token instanceof ServiceRecord)) {
17365 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17366 throw new IllegalArgumentException("Invalid service token");
17368 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17372 // =========================================================
17373 // BACKUP AND RESTORE
17374 // =========================================================
17376 // Cause the target app to be launched if necessary and its backup agent
17377 // instantiated. The backup agent will invoke backupAgentCreated() on the
17378 // activity manager to announce its creation.
17379 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17380 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17381 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17383 IPackageManager pm = AppGlobals.getPackageManager();
17384 ApplicationInfo app = null;
17386 app = pm.getApplicationInfo(packageName, 0, userId);
17387 } catch (RemoteException e) {
17388 // can't happen; package manager is process-local
17391 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17395 synchronized(this) {
17396 // !!! TODO: currently no check here that we're already bound
17397 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17398 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17399 synchronized (stats) {
17400 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17403 // Backup agent is now in use, its package can't be stopped.
17405 AppGlobals.getPackageManager().setPackageStoppedState(
17406 app.packageName, false, UserHandle.getUserId(app.uid));
17407 } catch (RemoteException e) {
17408 } catch (IllegalArgumentException e) {
17409 Slog.w(TAG, "Failed trying to unstop package "
17410 + app.packageName + ": " + e);
17413 BackupRecord r = new BackupRecord(ss, app, backupMode);
17414 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17415 ? new ComponentName(app.packageName, app.backupAgentName)
17416 : new ComponentName("android", "FullBackupAgent");
17417 // startProcessLocked() returns existing proc's record if it's already running
17418 ProcessRecord proc = startProcessLocked(app.processName, app,
17419 false, 0, "backup", hostingName, false, false, false);
17420 if (proc == null) {
17421 Slog.e(TAG, "Unable to start backup agent process " + r);
17425 // If the app is a regular app (uid >= 10000) and not the system server or phone
17426 // process, etc, then mark it as being in full backup so that certain calls to the
17427 // process can be blocked. This is not reset to false anywhere because we kill the
17428 // process after the full backup is done and the ProcessRecord will vaporize anyway.
17429 if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17430 proc.inFullBackup = true;
17434 mBackupAppName = app.packageName;
17436 // Try not to kill the process during backup
17437 updateOomAdjLocked(proc);
17439 // If the process is already attached, schedule the creation of the backup agent now.
17440 // If it is not yet live, this will be done when it attaches to the framework.
17441 if (proc.thread != null) {
17442 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17444 proc.thread.scheduleCreateBackupAgent(app,
17445 compatibilityInfoForPackageLocked(app), backupMode);
17446 } catch (RemoteException e) {
17447 // Will time out on the backup manager side
17450 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17452 // Invariants: at this point, the target app process exists and the application
17453 // is either already running or in the process of coming up. mBackupTarget and
17454 // mBackupAppName describe the app, so that when it binds back to the AM we
17455 // know that it's scheduled for a backup-agent operation.
17462 public void clearPendingBackup() {
17463 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17464 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17466 synchronized (this) {
17467 mBackupTarget = null;
17468 mBackupAppName = null;
17472 // A backup agent has just come up
17473 public void backupAgentCreated(String agentPackageName, IBinder agent) {
17474 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17477 synchronized(this) {
17478 if (!agentPackageName.equals(mBackupAppName)) {
17479 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17484 long oldIdent = Binder.clearCallingIdentity();
17486 IBackupManager bm = IBackupManager.Stub.asInterface(
17487 ServiceManager.getService(Context.BACKUP_SERVICE));
17488 bm.agentConnected(agentPackageName, agent);
17489 } catch (RemoteException e) {
17490 // can't happen; the backup manager service is local
17491 } catch (Exception e) {
17492 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17493 e.printStackTrace();
17495 Binder.restoreCallingIdentity(oldIdent);
17499 // done with this agent
17500 public void unbindBackupAgent(ApplicationInfo appInfo) {
17501 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17502 if (appInfo == null) {
17503 Slog.w(TAG, "unbind backup agent for null app");
17507 synchronized(this) {
17509 if (mBackupAppName == null) {
17510 Slog.w(TAG, "Unbinding backup agent with no active backup");
17514 if (!mBackupAppName.equals(appInfo.packageName)) {
17515 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17519 // Not backing this app up any more; reset its OOM adjustment
17520 final ProcessRecord proc = mBackupTarget.app;
17521 updateOomAdjLocked(proc);
17523 // If the app crashed during backup, 'thread' will be null here
17524 if (proc.thread != null) {
17526 proc.thread.scheduleDestroyBackupAgent(appInfo,
17527 compatibilityInfoForPackageLocked(appInfo));
17528 } catch (Exception e) {
17529 Slog.e(TAG, "Exception when unbinding backup agent:");
17530 e.printStackTrace();
17534 mBackupTarget = null;
17535 mBackupAppName = null;
17539 // =========================================================
17541 // =========================================================
17543 boolean isPendingBroadcastProcessLocked(int pid) {
17544 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17545 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17548 void skipPendingBroadcastLocked(int pid) {
17549 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17550 for (BroadcastQueue queue : mBroadcastQueues) {
17551 queue.skipPendingBroadcastLocked(pid);
17555 // The app just attached; send any pending broadcasts that it should receive
17556 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17557 boolean didSomething = false;
17558 for (BroadcastQueue queue : mBroadcastQueues) {
17559 didSomething |= queue.sendPendingBroadcastsLocked(app);
17561 return didSomething;
17564 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17565 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17566 enforceNotIsolatedCaller("registerReceiver");
17567 ArrayList<Intent> stickyIntents = null;
17568 ProcessRecord callerApp = null;
17571 synchronized(this) {
17572 if (caller != null) {
17573 callerApp = getRecordForAppLocked(caller);
17574 if (callerApp == null) {
17575 throw new SecurityException(
17576 "Unable to find app for caller " + caller
17577 + " (pid=" + Binder.getCallingPid()
17578 + ") when registering receiver " + receiver);
17580 if (callerApp.info.uid != Process.SYSTEM_UID &&
17581 !callerApp.pkgList.containsKey(callerPackage) &&
17582 !"android".equals(callerPackage)) {
17583 throw new SecurityException("Given caller package " + callerPackage
17584 + " is not running in process " + callerApp);
17586 callingUid = callerApp.info.uid;
17587 callingPid = callerApp.pid;
17589 callerPackage = null;
17590 callingUid = Binder.getCallingUid();
17591 callingPid = Binder.getCallingPid();
17594 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17595 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17597 Iterator<String> actions = filter.actionsIterator();
17598 if (actions == null) {
17599 ArrayList<String> noAction = new ArrayList<String>(1);
17600 noAction.add(null);
17601 actions = noAction.iterator();
17604 // Collect stickies of users
17605 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17606 while (actions.hasNext()) {
17607 String action = actions.next();
17608 for (int id : userIds) {
17609 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17610 if (stickies != null) {
17611 ArrayList<Intent> intents = stickies.get(action);
17612 if (intents != null) {
17613 if (stickyIntents == null) {
17614 stickyIntents = new ArrayList<Intent>();
17616 stickyIntents.addAll(intents);
17623 ArrayList<Intent> allSticky = null;
17624 if (stickyIntents != null) {
17625 final ContentResolver resolver = mContext.getContentResolver();
17626 // Look for any matching sticky broadcasts...
17627 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17628 Intent intent = stickyIntents.get(i);
17629 // If intent has scheme "content", it will need to acccess
17630 // provider that needs to lock mProviderMap in ActivityThread
17631 // and also it may need to wait application response, so we
17632 // cannot lock ActivityManagerService here.
17633 if (filter.match(resolver, intent, true, TAG) >= 0) {
17634 if (allSticky == null) {
17635 allSticky = new ArrayList<Intent>();
17637 allSticky.add(intent);
17642 // The first sticky in the list is returned directly back to the client.
17643 Intent sticky = allSticky != null ? allSticky.get(0) : null;
17644 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17645 if (receiver == null) {
17649 synchronized (this) {
17650 if (callerApp != null && (callerApp.thread == null
17651 || callerApp.thread.asBinder() != caller.asBinder())) {
17652 // Original caller already died
17655 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17657 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17659 if (rl.app != null) {
17660 rl.app.receivers.add(rl);
17663 receiver.asBinder().linkToDeath(rl, 0);
17664 } catch (RemoteException e) {
17667 rl.linkedToDeath = true;
17669 mRegisteredReceivers.put(receiver.asBinder(), rl);
17670 } else if (rl.uid != callingUid) {
17671 throw new IllegalArgumentException(
17672 "Receiver requested to register for uid " + callingUid
17673 + " was previously registered for uid " + rl.uid);
17674 } else if (rl.pid != callingPid) {
17675 throw new IllegalArgumentException(
17676 "Receiver requested to register for pid " + callingPid
17677 + " was previously registered for pid " + rl.pid);
17678 } else if (rl.userId != userId) {
17679 throw new IllegalArgumentException(
17680 "Receiver requested to register for user " + userId
17681 + " was previously registered for user " + rl.userId);
17683 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17684 permission, callingUid, userId);
17686 if (!bf.debugCheck()) {
17687 Slog.w(TAG, "==> For Dynamic broadcast");
17689 mReceiverResolver.addFilter(bf);
17691 // Enqueue broadcasts for all existing stickies that match
17693 if (allSticky != null) {
17694 ArrayList receivers = new ArrayList();
17697 final int stickyCount = allSticky.size();
17698 for (int i = 0; i < stickyCount; i++) {
17699 Intent intent = allSticky.get(i);
17700 BroadcastQueue queue = broadcastQueueForIntent(intent);
17701 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17702 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17703 null, 0, null, null, false, true, true, -1);
17704 queue.enqueueParallelBroadcastLocked(r);
17705 queue.scheduleBroadcastsLocked();
17713 public void unregisterReceiver(IIntentReceiver receiver) {
17714 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17716 final long origId = Binder.clearCallingIdentity();
17718 boolean doTrim = false;
17720 synchronized(this) {
17721 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17723 final BroadcastRecord r = rl.curBroadcast;
17724 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17725 final boolean doNext = r.queue.finishReceiverLocked(
17726 r, r.resultCode, r.resultData, r.resultExtras,
17727 r.resultAbort, false);
17730 r.queue.processNextBroadcast(false);
17734 if (rl.app != null) {
17735 rl.app.receivers.remove(rl);
17737 removeReceiverLocked(rl);
17738 if (rl.linkedToDeath) {
17739 rl.linkedToDeath = false;
17740 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17745 // If we actually concluded any broadcasts, we might now be able
17746 // to trim the recipients' apps from our working set
17748 trimApplications();
17753 Binder.restoreCallingIdentity(origId);
17757 void removeReceiverLocked(ReceiverList rl) {
17758 mRegisteredReceivers.remove(rl.receiver.asBinder());
17759 for (int i = rl.size() - 1; i >= 0; i--) {
17760 mReceiverResolver.removeFilter(rl.get(i));
17764 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17765 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17766 ProcessRecord r = mLruProcesses.get(i);
17767 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17769 r.thread.dispatchPackageBroadcast(cmd, packages);
17770 } catch (RemoteException ex) {
17776 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17777 int callingUid, int[] users) {
17778 // TODO: come back and remove this assumption to triage all broadcasts
17779 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17781 List<ResolveInfo> receivers = null;
17783 HashSet<ComponentName> singleUserReceivers = null;
17784 boolean scannedFirstReceivers = false;
17785 for (int user : users) {
17786 // Skip users that have Shell restrictions, with exception of always permitted
17787 // Shell broadcasts
17788 if (callingUid == Process.SHELL_UID
17789 && mUserController.hasUserRestriction(
17790 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17791 && !isPermittedShellBroadcast(intent)) {
17794 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17795 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17796 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17797 // If this is not the system user, we need to check for
17798 // any receivers that should be filtered out.
17799 for (int i=0; i<newReceivers.size(); i++) {
17800 ResolveInfo ri = newReceivers.get(i);
17801 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17802 newReceivers.remove(i);
17807 if (newReceivers != null && newReceivers.size() == 0) {
17808 newReceivers = null;
17810 if (receivers == null) {
17811 receivers = newReceivers;
17812 } else if (newReceivers != null) {
17813 // We need to concatenate the additional receivers
17814 // found with what we have do far. This would be easy,
17815 // but we also need to de-dup any receivers that are
17817 if (!scannedFirstReceivers) {
17818 // Collect any single user receivers we had already retrieved.
17819 scannedFirstReceivers = true;
17820 for (int i=0; i<receivers.size(); i++) {
17821 ResolveInfo ri = receivers.get(i);
17822 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17823 ComponentName cn = new ComponentName(
17824 ri.activityInfo.packageName, ri.activityInfo.name);
17825 if (singleUserReceivers == null) {
17826 singleUserReceivers = new HashSet<ComponentName>();
17828 singleUserReceivers.add(cn);
17832 // Add the new results to the existing results, tracking
17833 // and de-dupping single user receivers.
17834 for (int i=0; i<newReceivers.size(); i++) {
17835 ResolveInfo ri = newReceivers.get(i);
17836 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17837 ComponentName cn = new ComponentName(
17838 ri.activityInfo.packageName, ri.activityInfo.name);
17839 if (singleUserReceivers == null) {
17840 singleUserReceivers = new HashSet<ComponentName>();
17842 if (!singleUserReceivers.contains(cn)) {
17843 singleUserReceivers.add(cn);
17852 } catch (RemoteException ex) {
17853 // pm is in same process, this will never happen.
17858 private boolean isPermittedShellBroadcast(Intent intent) {
17859 // remote bugreport should always be allowed to be taken
17860 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17863 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17864 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17865 final String action = intent.getAction();
17866 if (isProtectedBroadcast
17867 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17868 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17869 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17870 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17871 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17872 || Intent.ACTION_MASTER_CLEAR.equals(action)
17873 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17874 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17875 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17876 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17877 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17878 // Broadcast is either protected, or it's a public action that
17879 // we've relaxed, so it's fine for system internals to send.
17883 // This broadcast may be a problem... but there are often system components that
17884 // want to send an internal broadcast to themselves, which is annoying to have to
17885 // explicitly list each action as a protected broadcast, so we will check for that
17886 // one safe case and allow it: an explicit broadcast, only being received by something
17887 // that has protected itself.
17888 if (receivers != null && receivers.size() > 0
17889 && (intent.getPackage() != null || intent.getComponent() != null)) {
17890 boolean allProtected = true;
17891 for (int i = receivers.size()-1; i >= 0; i--) {
17892 Object target = receivers.get(i);
17893 if (target instanceof ResolveInfo) {
17894 ResolveInfo ri = (ResolveInfo)target;
17895 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17896 allProtected = false;
17900 BroadcastFilter bf = (BroadcastFilter)target;
17901 if (bf.requiredPermission == null) {
17902 allProtected = false;
17907 if (allProtected) {
17913 // The vast majority of broadcasts sent from system internals
17914 // should be protected to avoid security holes, so yell loudly
17915 // to ensure we examine these cases.
17916 if (callerApp != null) {
17917 Log.wtf(TAG, "Sending non-protected broadcast " + action
17918 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17921 Log.wtf(TAG, "Sending non-protected broadcast " + action
17922 + " from system uid " + UserHandle.formatUid(callingUid)
17923 + " pkg " + callerPackage,
17928 final int broadcastIntentLocked(ProcessRecord callerApp,
17929 String callerPackage, Intent intent, String resolvedType,
17930 IIntentReceiver resultTo, int resultCode, String resultData,
17931 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17932 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17933 intent = new Intent(intent);
17935 // By default broadcasts do not go to stopped apps.
17936 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17938 // If we have not finished booting, don't allow this to launch new processes.
17939 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17940 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17943 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17944 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17945 + " ordered=" + ordered + " userid=" + userId);
17946 if ((resultTo != null) && !ordered) {
17947 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17950 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17951 ALLOW_NON_FULL, "broadcast", callerPackage);
17953 // Make sure that the user who is receiving this broadcast is running.
17954 // If not, we will just skip it. Make an exception for shutdown broadcasts
17955 // and upgrade steps.
17957 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17958 if ((callingUid != Process.SYSTEM_UID
17959 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17960 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17961 Slog.w(TAG, "Skipping broadcast of " + intent
17962 + ": user " + userId + " is stopped");
17963 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17967 BroadcastOptions brOptions = null;
17968 if (bOptions != null) {
17969 brOptions = new BroadcastOptions(bOptions);
17970 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17971 // See if the caller is allowed to do this. Note we are checking against
17972 // the actual real caller (not whoever provided the operation as say a
17973 // PendingIntent), because that who is actually supplied the arguments.
17974 if (checkComponentPermission(
17975 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17976 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17977 != PackageManager.PERMISSION_GRANTED) {
17978 String msg = "Permission Denial: " + intent.getAction()
17979 + " broadcast from " + callerPackage + " (pid=" + callingPid
17980 + ", uid=" + callingUid + ")"
17982 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17984 throw new SecurityException(msg);
17989 // Verify that protected broadcasts are only being sent by system code,
17990 // and that system code is only sending protected broadcasts.
17991 final String action = intent.getAction();
17992 final boolean isProtectedBroadcast;
17994 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17995 } catch (RemoteException e) {
17996 Slog.w(TAG, "Remote exception", e);
17997 return ActivityManager.BROADCAST_SUCCESS;
18000 final boolean isCallerSystem;
18001 switch (UserHandle.getAppId(callingUid)) {
18002 case Process.ROOT_UID:
18003 case Process.SYSTEM_UID:
18004 case Process.PHONE_UID:
18005 case Process.BLUETOOTH_UID:
18006 case Process.NFC_UID:
18007 isCallerSystem = true;
18010 isCallerSystem = (callerApp != null) && callerApp.persistent;
18014 // First line security check before anything else: stop non-system apps from
18015 // sending protected broadcasts.
18016 if (!isCallerSystem) {
18017 if (isProtectedBroadcast) {
18018 String msg = "Permission Denial: not allowed to send broadcast "
18019 + action + " from pid="
18020 + callingPid + ", uid=" + callingUid;
18022 throw new SecurityException(msg);
18024 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18025 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18026 // Special case for compatibility: we don't want apps to send this,
18027 // but historically it has not been protected and apps may be using it
18028 // to poke their own app widget. So, instead of making it protected,
18029 // just limit it to the caller.
18030 if (callerPackage == null) {
18031 String msg = "Permission Denial: not allowed to send broadcast "
18032 + action + " from unknown caller.";
18034 throw new SecurityException(msg);
18035 } else if (intent.getComponent() != null) {
18036 // They are good enough to send to an explicit component... verify
18037 // it is being sent to the calling app.
18038 if (!intent.getComponent().getPackageName().equals(
18040 String msg = "Permission Denial: not allowed to send broadcast "
18042 + intent.getComponent().getPackageName() + " from "
18045 throw new SecurityException(msg);
18048 // Limit broadcast to their own package.
18049 intent.setPackage(callerPackage);
18054 if (action != null) {
18056 case Intent.ACTION_UID_REMOVED:
18057 case Intent.ACTION_PACKAGE_REMOVED:
18058 case Intent.ACTION_PACKAGE_CHANGED:
18059 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18060 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18061 case Intent.ACTION_PACKAGES_SUSPENDED:
18062 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18063 // Handle special intents: if this broadcast is from the package
18064 // manager about a package being removed, we need to remove all of
18065 // its activities from the history stack.
18066 if (checkComponentPermission(
18067 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18068 callingPid, callingUid, -1, true)
18069 != PackageManager.PERMISSION_GRANTED) {
18070 String msg = "Permission Denial: " + intent.getAction()
18071 + " broadcast from " + callerPackage + " (pid=" + callingPid
18072 + ", uid=" + callingUid + ")"
18074 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18076 throw new SecurityException(msg);
18079 case Intent.ACTION_UID_REMOVED:
18080 final Bundle intentExtras = intent.getExtras();
18081 final int uid = intentExtras != null
18082 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18084 mBatteryStatsService.removeUid(uid);
18085 mAppOpsService.uidRemoved(uid);
18088 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18089 // If resources are unavailable just force stop all those packages
18090 // and flush the attribute cache as well.
18092 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18093 if (list != null && list.length > 0) {
18094 for (int i = 0; i < list.length; i++) {
18095 forceStopPackageLocked(list[i], -1, false, true, true,
18096 false, false, userId, "storage unmount");
18098 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18099 sendPackageBroadcastLocked(
18100 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18104 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18105 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18107 case Intent.ACTION_PACKAGE_REMOVED:
18108 case Intent.ACTION_PACKAGE_CHANGED:
18109 Uri data = intent.getData();
18111 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18112 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18113 final boolean replacing =
18114 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18115 final boolean killProcess =
18116 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18117 final boolean fullUninstall = removed && !replacing;
18120 forceStopPackageLocked(ssp, UserHandle.getAppId(
18121 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18122 false, true, true, false, fullUninstall, userId,
18123 removed ? "pkg removed" : "pkg changed");
18125 final int cmd = killProcess
18126 ? IApplicationThread.PACKAGE_REMOVED
18127 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18128 sendPackageBroadcastLocked(cmd,
18129 new String[] {ssp}, userId);
18130 if (fullUninstall) {
18131 mAppOpsService.packageRemoved(
18132 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18134 // Remove all permissions granted from/to this package
18135 removeUriPermissionsForPackageLocked(ssp, userId, true);
18137 removeTasksByPackageNameLocked(ssp, userId);
18139 // Hide the "unsupported display" dialog if necessary.
18140 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18141 mUnsupportedDisplaySizeDialog.getPackageName())) {
18142 mUnsupportedDisplaySizeDialog.dismiss();
18143 mUnsupportedDisplaySizeDialog = null;
18145 mCompatModePackages.handlePackageUninstalledLocked(ssp);
18146 mBatteryStatsService.notePackageUninstalled(ssp);
18150 killPackageProcessesLocked(ssp, UserHandle.getAppId(
18151 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18152 userId, ProcessList.INVALID_ADJ,
18153 false, true, true, false, "change " + ssp);
18155 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18156 intent.getStringArrayExtra(
18157 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18161 case Intent.ACTION_PACKAGES_SUSPENDED:
18162 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18163 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18164 intent.getAction());
18165 final String[] packageNames = intent.getStringArrayExtra(
18166 Intent.EXTRA_CHANGED_PACKAGE_LIST);
18167 final int userHandle = intent.getIntExtra(
18168 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18170 synchronized(ActivityManagerService.this) {
18171 mRecentTasks.onPackagesSuspendedChanged(
18172 packageNames, suspended, userHandle);
18177 case Intent.ACTION_PACKAGE_REPLACED:
18179 final Uri data = intent.getData();
18181 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18182 final ApplicationInfo aInfo =
18183 getPackageManagerInternalLocked().getApplicationInfo(
18186 if (aInfo == null) {
18187 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18188 + " ssp=" + ssp + " data=" + data);
18189 return ActivityManager.BROADCAST_SUCCESS;
18191 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18192 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18193 new String[] {ssp}, userId);
18197 case Intent.ACTION_PACKAGE_ADDED:
18199 // Special case for adding a package: by default turn on compatibility mode.
18200 Uri data = intent.getData();
18202 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18203 final boolean replacing =
18204 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18205 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18208 ApplicationInfo ai = AppGlobals.getPackageManager().
18209 getApplicationInfo(ssp, 0, 0);
18210 mBatteryStatsService.notePackageInstalled(ssp,
18211 ai != null ? ai.versionCode : 0);
18212 } catch (RemoteException e) {
18217 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18219 Uri data = intent.getData();
18221 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18222 // Hide the "unsupported display" dialog if necessary.
18223 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18224 mUnsupportedDisplaySizeDialog.getPackageName())) {
18225 mUnsupportedDisplaySizeDialog.dismiss();
18226 mUnsupportedDisplaySizeDialog = null;
18228 mCompatModePackages.handlePackageDataClearedLocked(ssp);
18232 case Intent.ACTION_TIMEZONE_CHANGED:
18233 // If this is the time zone changed action, queue up a message that will reset
18234 // the timezone of all currently running processes. This message will get
18235 // queued up before the broadcast happens.
18236 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18238 case Intent.ACTION_TIME_CHANGED:
18239 // If the user set the time, let all running processes know.
18240 final int is24Hour =
18241 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18243 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18244 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18245 synchronized (stats) {
18246 stats.noteCurrentTimeChangedLocked();
18249 case Intent.ACTION_CLEAR_DNS_CACHE:
18250 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18252 case Proxy.PROXY_CHANGE_ACTION:
18253 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18254 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18256 case android.hardware.Camera.ACTION_NEW_PICTURE:
18257 case android.hardware.Camera.ACTION_NEW_VIDEO:
18258 // These broadcasts are no longer allowed by the system, since they can
18259 // cause significant thrashing at a crictical point (using the camera).
18260 // Apps should use JobScehduler to monitor for media provider changes.
18261 Slog.w(TAG, action + " no longer allowed; dropping from "
18262 + UserHandle.formatUid(callingUid));
18263 if (resultTo != null) {
18264 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18266 queue.performReceiveLocked(callerApp, resultTo, intent,
18267 Activity.RESULT_CANCELED, null, null,
18268 false, false, userId);
18269 } catch (RemoteException e) {
18270 Slog.w(TAG, "Failure ["
18271 + queue.mQueueName + "] sending broadcast result of "
18276 // Lie; we don't want to crash the app.
18277 return ActivityManager.BROADCAST_SUCCESS;
18281 // Add to the sticky list if requested.
18283 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18284 callingPid, callingUid)
18285 != PackageManager.PERMISSION_GRANTED) {
18286 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18287 + callingPid + ", uid=" + callingUid
18288 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18290 throw new SecurityException(msg);
18292 if (requiredPermissions != null && requiredPermissions.length > 0) {
18293 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18294 + " and enforce permissions " + Arrays.toString(requiredPermissions));
18295 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18297 if (intent.getComponent() != null) {
18298 throw new SecurityException(
18299 "Sticky broadcasts can't target a specific component");
18301 // We use userId directly here, since the "all" target is maintained
18302 // as a separate set of sticky broadcasts.
18303 if (userId != UserHandle.USER_ALL) {
18304 // But first, if this is not a broadcast to all users, then
18305 // make sure it doesn't conflict with an existing broadcast to
18307 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18308 UserHandle.USER_ALL);
18309 if (stickies != null) {
18310 ArrayList<Intent> list = stickies.get(intent.getAction());
18311 if (list != null) {
18312 int N = list.size();
18314 for (i=0; i<N; i++) {
18315 if (intent.filterEquals(list.get(i))) {
18316 throw new IllegalArgumentException(
18317 "Sticky broadcast " + intent + " for user "
18318 + userId + " conflicts with existing global broadcast");
18324 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18325 if (stickies == null) {
18326 stickies = new ArrayMap<>();
18327 mStickyBroadcasts.put(userId, stickies);
18329 ArrayList<Intent> list = stickies.get(intent.getAction());
18330 if (list == null) {
18331 list = new ArrayList<>();
18332 stickies.put(intent.getAction(), list);
18334 final int stickiesCount = list.size();
18336 for (i = 0; i < stickiesCount; i++) {
18337 if (intent.filterEquals(list.get(i))) {
18338 // This sticky already exists, replace it.
18339 list.set(i, new Intent(intent));
18343 if (i >= stickiesCount) {
18344 list.add(new Intent(intent));
18349 if (userId == UserHandle.USER_ALL) {
18350 // Caller wants broadcast to go to all started users.
18351 users = mUserController.getStartedUserArrayLocked();
18353 // Caller wants broadcast to go to one specific user.
18354 users = new int[] {userId};
18357 // Figure out who all will receive this broadcast.
18358 List receivers = null;
18359 List<BroadcastFilter> registeredReceivers = null;
18360 // Need to resolve the intent to interested receivers...
18361 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18363 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18365 if (intent.getComponent() == null) {
18366 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18367 // Query one target user at a time, excluding shell-restricted users
18368 for (int i = 0; i < users.length; i++) {
18369 if (mUserController.hasUserRestriction(
18370 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18373 List<BroadcastFilter> registeredReceiversForUser =
18374 mReceiverResolver.queryIntent(intent,
18375 resolvedType, false, users[i]);
18376 if (registeredReceivers == null) {
18377 registeredReceivers = registeredReceiversForUser;
18378 } else if (registeredReceiversForUser != null) {
18379 registeredReceivers.addAll(registeredReceiversForUser);
18383 registeredReceivers = mReceiverResolver.queryIntent(intent,
18384 resolvedType, false, userId);
18388 final boolean replacePending =
18389 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18391 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18392 + " replacePending=" + replacePending);
18394 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18395 if (!ordered && NR > 0) {
18396 // If we are not serializing this broadcast, then send the
18397 // registered receivers separately so they don't wait for the
18398 // components to be launched.
18399 if (isCallerSystem) {
18400 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18401 isProtectedBroadcast, registeredReceivers);
18403 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18404 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18405 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18406 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18407 resultExtras, ordered, sticky, false, userId);
18408 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18409 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18411 queue.enqueueParallelBroadcastLocked(r);
18412 queue.scheduleBroadcastsLocked();
18414 registeredReceivers = null;
18418 // Merge into one list.
18420 if (receivers != null) {
18421 // A special case for PACKAGE_ADDED: do not allow the package
18422 // being added to see this broadcast. This prevents them from
18423 // using this as a back door to get run as soon as they are
18424 // installed. Maybe in the future we want to have a special install
18425 // broadcast or such for apps, but we'd like to deliberately make
18427 String skipPackages[] = null;
18428 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18429 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18430 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18431 Uri data = intent.getData();
18432 if (data != null) {
18433 String pkgName = data.getSchemeSpecificPart();
18434 if (pkgName != null) {
18435 skipPackages = new String[] { pkgName };
18438 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18439 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18441 if (skipPackages != null && (skipPackages.length > 0)) {
18442 for (String skipPackage : skipPackages) {
18443 if (skipPackage != null) {
18444 int NT = receivers.size();
18445 for (int it=0; it<NT; it++) {
18446 ResolveInfo curt = (ResolveInfo)receivers.get(it);
18447 if (curt.activityInfo.packageName.equals(skipPackage)) {
18448 receivers.remove(it);
18457 int NT = receivers != null ? receivers.size() : 0;
18459 ResolveInfo curt = null;
18460 BroadcastFilter curr = null;
18461 while (it < NT && ir < NR) {
18462 if (curt == null) {
18463 curt = (ResolveInfo)receivers.get(it);
18465 if (curr == null) {
18466 curr = registeredReceivers.get(ir);
18468 if (curr.getPriority() >= curt.priority) {
18469 // Insert this broadcast record into the final list.
18470 receivers.add(it, curr);
18476 // Skip to the next ResolveInfo in the final list.
18483 if (receivers == null) {
18484 receivers = new ArrayList();
18486 receivers.add(registeredReceivers.get(ir));
18490 if (isCallerSystem) {
18491 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18492 isProtectedBroadcast, receivers);
18495 if ((receivers != null && receivers.size() > 0)
18496 || resultTo != null) {
18497 BroadcastQueue queue = broadcastQueueForIntent(intent);
18498 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18499 callerPackage, callingPid, callingUid, resolvedType,
18500 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18501 resultData, resultExtras, ordered, sticky, false, userId);
18503 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18504 + ": prev had " + queue.mOrderedBroadcasts.size());
18505 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18506 "Enqueueing broadcast " + r.intent.getAction());
18508 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18510 queue.enqueueOrderedBroadcastLocked(r);
18511 queue.scheduleBroadcastsLocked();
18514 // There was nobody interested in the broadcast, but we still want to record
18515 // that it happened.
18516 if (intent.getComponent() == null && intent.getPackage() == null
18517 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18518 // This was an implicit broadcast... let's record it for posterity.
18519 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18523 return ActivityManager.BROADCAST_SUCCESS;
18526 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18527 int skipCount, long dispatchTime) {
18528 final long now = SystemClock.elapsedRealtime();
18529 if (mCurBroadcastStats == null ||
18530 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18531 mLastBroadcastStats = mCurBroadcastStats;
18532 if (mLastBroadcastStats != null) {
18533 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18534 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18536 mCurBroadcastStats = new BroadcastStats();
18538 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18541 final Intent verifyBroadcastLocked(Intent intent) {
18542 // Refuse possible leaked file descriptors
18543 if (intent != null && intent.hasFileDescriptors() == true) {
18544 throw new IllegalArgumentException("File descriptors passed in Intent");
18547 int flags = intent.getFlags();
18549 if (!mProcessesReady) {
18550 // if the caller really truly claims to know what they're doing, go
18551 // ahead and allow the broadcast without launching any receivers
18552 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18553 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18554 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18555 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18556 + " before boot completion");
18557 throw new IllegalStateException("Cannot broadcast before boot completed");
18561 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18562 throw new IllegalArgumentException(
18563 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18569 public final int broadcastIntent(IApplicationThread caller,
18570 Intent intent, String resolvedType, IIntentReceiver resultTo,
18571 int resultCode, String resultData, Bundle resultExtras,
18572 String[] requiredPermissions, int appOp, Bundle bOptions,
18573 boolean serialized, boolean sticky, int userId) {
18574 enforceNotIsolatedCaller("broadcastIntent");
18575 synchronized(this) {
18576 intent = verifyBroadcastLocked(intent);
18578 final ProcessRecord callerApp = getRecordForAppLocked(caller);
18579 final int callingPid = Binder.getCallingPid();
18580 final int callingUid = Binder.getCallingUid();
18581 final long origId = Binder.clearCallingIdentity();
18582 int res = broadcastIntentLocked(callerApp,
18583 callerApp != null ? callerApp.info.packageName : null,
18584 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18585 requiredPermissions, appOp, bOptions, serialized, sticky,
18586 callingPid, callingUid, userId);
18587 Binder.restoreCallingIdentity(origId);
18593 int broadcastIntentInPackage(String packageName, int uid,
18594 Intent intent, String resolvedType, IIntentReceiver resultTo,
18595 int resultCode, String resultData, Bundle resultExtras,
18596 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18598 synchronized(this) {
18599 intent = verifyBroadcastLocked(intent);
18601 final long origId = Binder.clearCallingIdentity();
18602 String[] requiredPermissions = requiredPermission == null ? null
18603 : new String[] {requiredPermission};
18604 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18605 resultTo, resultCode, resultData, resultExtras,
18606 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18607 sticky, -1, uid, userId);
18608 Binder.restoreCallingIdentity(origId);
18613 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18614 // Refuse possible leaked file descriptors
18615 if (intent != null && intent.hasFileDescriptors() == true) {
18616 throw new IllegalArgumentException("File descriptors passed in Intent");
18619 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18620 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18622 synchronized(this) {
18623 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18624 != PackageManager.PERMISSION_GRANTED) {
18625 String msg = "Permission Denial: unbroadcastIntent() from pid="
18626 + Binder.getCallingPid()
18627 + ", uid=" + Binder.getCallingUid()
18628 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18630 throw new SecurityException(msg);
18632 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18633 if (stickies != null) {
18634 ArrayList<Intent> list = stickies.get(intent.getAction());
18635 if (list != null) {
18636 int N = list.size();
18638 for (i=0; i<N; i++) {
18639 if (intent.filterEquals(list.get(i))) {
18644 if (list.size() <= 0) {
18645 stickies.remove(intent.getAction());
18648 if (stickies.size() <= 0) {
18649 mStickyBroadcasts.remove(userId);
18655 void backgroundServicesFinishedLocked(int userId) {
18656 for (BroadcastQueue queue : mBroadcastQueues) {
18657 queue.backgroundServicesFinishedLocked(userId);
18661 public void finishReceiver(IBinder who, int resultCode, String resultData,
18662 Bundle resultExtras, boolean resultAbort, int flags) {
18663 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18665 // Refuse possible leaked file descriptors
18666 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18667 throw new IllegalArgumentException("File descriptors passed in Bundle");
18670 final long origId = Binder.clearCallingIdentity();
18672 boolean doNext = false;
18675 synchronized(this) {
18676 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18677 ? mFgBroadcastQueue : mBgBroadcastQueue;
18678 r = queue.getMatchingOrderedReceiver(who);
18680 doNext = r.queue.finishReceiverLocked(r, resultCode,
18681 resultData, resultExtras, resultAbort, true);
18686 r.queue.processNextBroadcast(false);
18688 trimApplications();
18690 Binder.restoreCallingIdentity(origId);
18694 // =========================================================
18696 // =========================================================
18698 public boolean startInstrumentation(ComponentName className,
18699 String profileFile, int flags, Bundle arguments,
18700 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18701 int userId, String abiOverride) {
18702 enforceNotIsolatedCaller("startInstrumentation");
18703 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18704 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18705 // Refuse possible leaked file descriptors
18706 if (arguments != null && arguments.hasFileDescriptors()) {
18707 throw new IllegalArgumentException("File descriptors passed in Bundle");
18710 synchronized(this) {
18711 InstrumentationInfo ii = null;
18712 ApplicationInfo ai = null;
18714 ii = mContext.getPackageManager().getInstrumentationInfo(
18715 className, STOCK_PM_FLAGS);
18716 ai = AppGlobals.getPackageManager().getApplicationInfo(
18717 ii.targetPackage, STOCK_PM_FLAGS, userId);
18718 } catch (PackageManager.NameNotFoundException e) {
18719 } catch (RemoteException e) {
18722 reportStartInstrumentationFailureLocked(watcher, className,
18723 "Unable to find instrumentation info for: " + className);
18727 reportStartInstrumentationFailureLocked(watcher, className,
18728 "Unable to find instrumentation target package: " + ii.targetPackage);
18731 if (!ai.hasCode()) {
18732 reportStartInstrumentationFailureLocked(watcher, className,
18733 "Instrumentation target has no code: " + ii.targetPackage);
18737 int match = mContext.getPackageManager().checkSignatures(
18738 ii.targetPackage, ii.packageName);
18739 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18740 String msg = "Permission Denial: starting instrumentation "
18741 + className + " from pid="
18742 + Binder.getCallingPid()
18743 + ", uid=" + Binder.getCallingPid()
18744 + " not allowed because package " + ii.packageName
18745 + " does not have a signature matching the target "
18746 + ii.targetPackage;
18747 reportStartInstrumentationFailureLocked(watcher, className, msg);
18748 throw new SecurityException(msg);
18751 final long origId = Binder.clearCallingIdentity();
18752 // Instrumentation can kill and relaunch even persistent processes
18753 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18755 ProcessRecord app = addAppLocked(ai, false, abiOverride);
18756 app.instrumentationClass = className;
18757 app.instrumentationInfo = ai;
18758 app.instrumentationProfileFile = profileFile;
18759 app.instrumentationArguments = arguments;
18760 app.instrumentationWatcher = watcher;
18761 app.instrumentationUiAutomationConnection = uiAutomationConnection;
18762 app.instrumentationResultClass = className;
18763 Binder.restoreCallingIdentity(origId);
18770 * Report errors that occur while attempting to start Instrumentation. Always writes the
18771 * error to the logs, but if somebody is watching, send the report there too. This enables
18772 * the "am" command to report errors with more information.
18774 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
18775 * @param cn The component name of the instrumentation.
18776 * @param report The error report.
18778 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18779 ComponentName cn, String report) {
18780 Slog.w(TAG, report);
18781 if (watcher != null) {
18782 Bundle results = new Bundle();
18783 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18784 results.putString("Error", report);
18785 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18789 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18790 if (app.instrumentationWatcher != null) {
18791 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18792 app.instrumentationClass, resultCode, results);
18795 // Can't call out of the system process with a lock held, so post a message.
18796 if (app.instrumentationUiAutomationConnection != null) {
18797 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18798 app.instrumentationUiAutomationConnection).sendToTarget();
18801 app.instrumentationWatcher = null;
18802 app.instrumentationUiAutomationConnection = null;
18803 app.instrumentationClass = null;
18804 app.instrumentationInfo = null;
18805 app.instrumentationProfileFile = null;
18806 app.instrumentationArguments = null;
18808 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18812 public void finishInstrumentation(IApplicationThread target,
18813 int resultCode, Bundle results) {
18814 int userId = UserHandle.getCallingUserId();
18815 // Refuse possible leaked file descriptors
18816 if (results != null && results.hasFileDescriptors()) {
18817 throw new IllegalArgumentException("File descriptors passed in Intent");
18820 synchronized(this) {
18821 ProcessRecord app = getRecordForAppLocked(target);
18823 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18826 final long origId = Binder.clearCallingIdentity();
18827 finishInstrumentationLocked(app, resultCode, results);
18828 Binder.restoreCallingIdentity(origId);
18832 // =========================================================
18834 // =========================================================
18836 public ConfigurationInfo getDeviceConfigurationInfo() {
18837 ConfigurationInfo config = new ConfigurationInfo();
18838 synchronized (this) {
18839 config.reqTouchScreen = mConfiguration.touchscreen;
18840 config.reqKeyboardType = mConfiguration.keyboard;
18841 config.reqNavigation = mConfiguration.navigation;
18842 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18843 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18844 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18846 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18847 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18848 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18850 config.reqGlEsVersion = GL_ES_VERSION;
18855 ActivityStack getFocusedStack() {
18856 return mStackSupervisor.getFocusedStack();
18860 public int getFocusedStackId() throws RemoteException {
18861 ActivityStack focusedStack = getFocusedStack();
18862 if (focusedStack != null) {
18863 return focusedStack.getStackId();
18868 public Configuration getConfiguration() {
18870 synchronized(this) {
18871 ci = new Configuration(mConfiguration);
18872 ci.userSetLocale = false;
18878 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18879 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18880 synchronized (this) {
18881 mSuppressResizeConfigChanges = suppress;
18886 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18887 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18888 if (fromStackId == HOME_STACK_ID) {
18889 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18891 synchronized (this) {
18892 final long origId = Binder.clearCallingIdentity();
18894 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18896 Binder.restoreCallingIdentity(origId);
18902 public void updatePersistentConfiguration(Configuration values) {
18903 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18904 "updateConfiguration()");
18905 enforceWriteSettingsPermission("updateConfiguration()");
18906 if (values == null) {
18907 throw new NullPointerException("Configuration must not be null");
18910 int userId = UserHandle.getCallingUserId();
18912 synchronized(this) {
18913 updatePersistentConfigurationLocked(values, userId);
18917 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18918 final long origId = Binder.clearCallingIdentity();
18920 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18922 Binder.restoreCallingIdentity(origId);
18926 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18927 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18928 FONT_SCALE, 1.0f, userId);
18929 if (mConfiguration.fontScale != scaleFactor) {
18930 final Configuration configuration = mWindowManager.computeNewConfiguration();
18931 configuration.fontScale = scaleFactor;
18932 synchronized (this) {
18933 updatePersistentConfigurationLocked(configuration, userId);
18938 private void enforceWriteSettingsPermission(String func) {
18939 int uid = Binder.getCallingUid();
18940 if (uid == Process.ROOT_UID) {
18944 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18945 Settings.getPackageNameForUid(mContext, uid), false)) {
18949 String msg = "Permission Denial: " + func + " from pid="
18950 + Binder.getCallingPid()
18952 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18954 throw new SecurityException(msg);
18957 public void updateConfiguration(Configuration values) {
18958 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18959 "updateConfiguration()");
18961 synchronized(this) {
18962 if (values == null && mWindowManager != null) {
18963 // sentinel: fetch the current configuration from the window manager
18964 values = mWindowManager.computeNewConfiguration();
18967 if (mWindowManager != null) {
18968 mProcessList.applyDisplaySize(mWindowManager);
18971 final long origId = Binder.clearCallingIdentity();
18972 if (values != null) {
18973 Settings.System.clearConfiguration(values);
18975 updateConfigurationLocked(values, null, false);
18976 Binder.restoreCallingIdentity(origId);
18980 void updateUserConfigurationLocked() {
18981 Configuration configuration = new Configuration(mConfiguration);
18982 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18983 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18984 updateConfigurationLocked(configuration, null, false);
18987 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18988 boolean initLocale) {
18989 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18992 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18993 boolean initLocale, boolean deferResume) {
18994 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18995 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18996 UserHandle.USER_NULL, deferResume);
18999 // To cache the list of supported system locales
19000 private String[] mSupportedSystemLocales = null;
19003 * Do either or both things: (1) change the current configuration, and (2)
19004 * make sure the given activity is running with the (now) current
19005 * configuration. Returns true if the activity has been left running, or
19006 * false if <var>starting</var> is being destroyed to match the new
19009 * @param userId is only used when persistent parameter is set to true to persist configuration
19010 * for that particular user
19012 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19013 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19016 if (mWindowManager != null) {
19017 mWindowManager.deferSurfaceLayout();
19019 if (values != null) {
19020 Configuration newConfig = new Configuration(mConfiguration);
19021 changes = newConfig.updateFrom(values);
19022 if (changes != 0) {
19023 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19024 "Updating configuration to: " + values);
19026 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19028 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19029 final LocaleList locales = values.getLocales();
19030 int bestLocaleIndex = 0;
19031 if (locales.size() > 1) {
19032 if (mSupportedSystemLocales == null) {
19033 mSupportedSystemLocales =
19034 Resources.getSystem().getAssets().getLocales();
19036 bestLocaleIndex = Math.max(0,
19037 locales.getFirstMatchIndex(mSupportedSystemLocales));
19039 SystemProperties.set("persist.sys.locale",
19040 locales.get(bestLocaleIndex).toLanguageTag());
19041 LocaleList.setDefault(locales, bestLocaleIndex);
19042 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19043 locales.get(bestLocaleIndex)));
19046 mConfigurationSeq++;
19047 if (mConfigurationSeq <= 0) {
19048 mConfigurationSeq = 1;
19050 newConfig.seq = mConfigurationSeq;
19051 mConfiguration = newConfig;
19052 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19053 mUsageStatsService.reportConfigurationChange(newConfig,
19054 mUserController.getCurrentUserIdLocked());
19055 //mUsageStatsService.noteStartConfig(newConfig);
19057 final Configuration configCopy = new Configuration(mConfiguration);
19059 // TODO: If our config changes, should we auto dismiss any currently
19060 // showing dialogs?
19061 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19063 AttributeCache ac = AttributeCache.instance();
19065 ac.updateConfiguration(configCopy);
19068 // Make sure all resources in our process are updated
19069 // right now, so that anyone who is going to retrieve
19070 // resource values after we return will be sure to get
19071 // the new ones. This is especially important during
19072 // boot, where the first config change needs to guarantee
19073 // all resources have that config before following boot
19074 // code is executed.
19075 mSystemThread.applyConfigurationToResources(configCopy);
19077 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19078 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19079 msg.obj = new Configuration(configCopy);
19081 mHandler.sendMessage(msg);
19084 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19085 if (isDensityChange) {
19086 // Reset the unsupported display size dialog.
19087 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19089 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19090 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19093 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19094 ProcessRecord app = mLruProcesses.get(i);
19096 if (app.thread != null) {
19097 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19098 + app.processName + " new config " + mConfiguration);
19099 app.thread.scheduleConfigurationChanged(configCopy);
19101 } catch (Exception e) {
19104 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19105 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19106 | Intent.FLAG_RECEIVER_REPLACE_PENDING
19107 | Intent.FLAG_RECEIVER_FOREGROUND);
19108 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19109 null, AppOpsManager.OP_NONE, null, false, false,
19110 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19111 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19112 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19113 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19114 if (initLocale || !mProcessesReady) {
19115 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19117 broadcastIntentLocked(null, null, intent,
19118 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19119 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19122 // Update the configuration with WM first and check if any of the stacks need to be
19123 // resized due to the configuration change. If so, resize the stacks now and do any
19124 // relaunches if necessary. This way we don't need to relaunch again below in
19125 // ensureActivityConfigurationLocked().
19126 if (mWindowManager != null) {
19127 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19128 if (resizedStacks != null) {
19129 for (int stackId : resizedStacks) {
19130 final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19131 mStackSupervisor.resizeStackLocked(
19132 stackId, newBounds, null, null, false, false, deferResume);
19138 boolean kept = true;
19139 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19140 // mainStack is null during startup.
19141 if (mainStack != null) {
19142 if (changes != 0 && starting == null) {
19143 // If the configuration changed, and the caller is not already
19144 // in the process of starting an activity, then find the top
19145 // activity to check if its configuration needs to change.
19146 starting = mainStack.topRunningActivityLocked();
19149 if (starting != null) {
19150 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19151 // And we need to make sure at this point that all other activities
19152 // are made visible with the correct configuration.
19153 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19154 !PRESERVE_WINDOWS);
19157 if (mWindowManager != null) {
19158 mWindowManager.continueSurfaceLayout();
19164 * Decide based on the configuration whether we should shouw the ANR,
19165 * crash, etc dialogs. The idea is that if there is no affordence to
19166 * press the on-screen buttons, or the user experience would be more
19167 * greatly impacted than the crash itself, we shouldn't show the dialog.
19169 * A thought: SystemUI might also want to get told about this, the Power
19170 * dialog / global actions also might want different behaviors.
19172 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19173 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19174 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19175 && config.navigation == Configuration.NAVIGATION_NONAV);
19176 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19177 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19178 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19179 return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19183 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19184 synchronized (this) {
19185 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19186 if (srec != null) {
19187 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19193 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19194 Intent resultData) {
19196 synchronized (this) {
19197 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19199 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19205 public int getLaunchedFromUid(IBinder activityToken) {
19206 ActivityRecord srec;
19207 synchronized (this) {
19208 srec = ActivityRecord.forTokenLocked(activityToken);
19210 if (srec == null) {
19213 return srec.launchedFromUid;
19216 public String getLaunchedFromPackage(IBinder activityToken) {
19217 ActivityRecord srec;
19218 synchronized (this) {
19219 srec = ActivityRecord.forTokenLocked(activityToken);
19221 if (srec == null) {
19224 return srec.launchedFromPackage;
19227 // =========================================================
19228 // LIFETIME MANAGEMENT
19229 // =========================================================
19231 // Returns which broadcast queue the app is the current [or imminent] receiver
19232 // on, or 'null' if the app is not an active broadcast recipient.
19233 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19234 BroadcastRecord r = app.curReceiver;
19239 // It's not the current receiver, but it might be starting up to become one
19240 synchronized (this) {
19241 for (BroadcastQueue queue : mBroadcastQueues) {
19242 r = queue.mPendingBroadcast;
19243 if (r != null && r.curApp == app) {
19244 // found it; report which queue it's in
19253 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19254 int targetUid, ComponentName targetComponent, String targetProcess) {
19255 if (!mTrackingAssociations) {
19258 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19259 = mAssociations.get(targetUid);
19260 if (components == null) {
19261 components = new ArrayMap<>();
19262 mAssociations.put(targetUid, components);
19264 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19265 if (sourceUids == null) {
19266 sourceUids = new SparseArray<>();
19267 components.put(targetComponent, sourceUids);
19269 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19270 if (sourceProcesses == null) {
19271 sourceProcesses = new ArrayMap<>();
19272 sourceUids.put(sourceUid, sourceProcesses);
19274 Association ass = sourceProcesses.get(sourceProcess);
19276 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19278 sourceProcesses.put(sourceProcess, ass);
19282 if (ass.mNesting == 1) {
19283 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19284 ass.mLastState = sourceState;
19289 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19290 ComponentName targetComponent) {
19291 if (!mTrackingAssociations) {
19294 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19295 = mAssociations.get(targetUid);
19296 if (components == null) {
19299 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19300 if (sourceUids == null) {
19303 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19304 if (sourceProcesses == null) {
19307 Association ass = sourceProcesses.get(sourceProcess);
19308 if (ass == null || ass.mNesting <= 0) {
19312 if (ass.mNesting == 0) {
19313 long uptime = SystemClock.uptimeMillis();
19314 ass.mTime += uptime - ass.mStartTime;
19315 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19316 += uptime - ass.mLastStateUptime;
19317 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19321 private void noteUidProcessState(final int uid, final int state) {
19322 mBatteryStatsService.noteUidProcessState(uid, state);
19323 if (mTrackingAssociations) {
19324 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19325 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19326 = mAssociations.valueAt(i1);
19327 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19328 SparseArray<ArrayMap<String, Association>> sourceUids
19329 = targetComponents.valueAt(i2);
19330 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19331 if (sourceProcesses != null) {
19332 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19333 Association ass = sourceProcesses.valueAt(i4);
19334 if (ass.mNesting >= 1) {
19335 // currently associated
19336 long uptime = SystemClock.uptimeMillis();
19337 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19338 += uptime - ass.mLastStateUptime;
19339 ass.mLastState = state;
19340 ass.mLastStateUptime = uptime;
19349 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19350 boolean doingAll, long now) {
19351 if (mAdjSeq == app.adjSeq) {
19352 // This adjustment has already been computed.
19353 return app.curRawAdj;
19356 if (app.thread == null) {
19357 app.adjSeq = mAdjSeq;
19358 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19359 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19360 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19363 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19364 app.adjSource = null;
19365 app.adjTarget = null;
19367 app.cached = false;
19369 final int activitiesSize = app.activities.size();
19371 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19372 // The max adjustment doesn't allow this app to be anything
19373 // below foreground, so it is not worth doing work for it.
19374 app.adjType = "fixed";
19375 app.adjSeq = mAdjSeq;
19376 app.curRawAdj = app.maxAdj;
19377 app.foregroundActivities = false;
19378 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19379 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19380 // System processes can do UI, and when they do we want to have
19381 // them trim their memory after the user leaves the UI. To
19382 // facilitate this, here we need to determine whether or not it
19383 // is currently showing UI.
19384 app.systemNoUi = true;
19385 if (app == TOP_APP) {
19386 app.systemNoUi = false;
19387 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19388 app.adjType = "pers-top-activity";
19389 } else if (app.hasTopUi) {
19390 app.systemNoUi = false;
19391 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19392 app.adjType = "pers-top-ui";
19393 } else if (activitiesSize > 0) {
19394 for (int j = 0; j < activitiesSize; j++) {
19395 final ActivityRecord r = app.activities.get(j);
19397 app.systemNoUi = false;
19401 if (!app.systemNoUi) {
19402 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19404 return (app.curAdj=app.maxAdj);
19407 app.systemNoUi = false;
19409 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19411 // Determine the importance of the process, starting with most
19412 // important to least, and assign an appropriate OOM adjustment.
19416 boolean foregroundActivities = false;
19417 BroadcastQueue queue;
19418 if (app == TOP_APP) {
19419 // The last app on the list is the foreground app.
19420 adj = ProcessList.FOREGROUND_APP_ADJ;
19421 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19422 app.adjType = "top-activity";
19423 foregroundActivities = true;
19424 procState = PROCESS_STATE_CUR_TOP;
19425 } else if (app.instrumentationClass != null) {
19426 // Don't want to kill running instrumentation.
19427 adj = ProcessList.FOREGROUND_APP_ADJ;
19428 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19429 app.adjType = "instrumentation";
19430 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19431 } else if ((queue = isReceivingBroadcast(app)) != null) {
19432 // An app that is currently receiving a broadcast also
19433 // counts as being in the foreground for OOM killer purposes.
19434 // It's placed in a sched group based on the nature of the
19435 // broadcast as reflected by which queue it's active in.
19436 adj = ProcessList.FOREGROUND_APP_ADJ;
19437 schedGroup = (queue == mFgBroadcastQueue)
19438 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19439 app.adjType = "broadcast";
19440 procState = ActivityManager.PROCESS_STATE_RECEIVER;
19441 } else if (app.executingServices.size() > 0) {
19442 // An app that is currently executing a service callback also
19443 // counts as being in the foreground.
19444 adj = ProcessList.FOREGROUND_APP_ADJ;
19445 schedGroup = app.execServicesFg ?
19446 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19447 app.adjType = "exec-service";
19448 procState = ActivityManager.PROCESS_STATE_SERVICE;
19449 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19451 // As far as we know the process is empty. We may change our mind later.
19452 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19453 // At this point we don't actually know the adjustment. Use the cached adj
19454 // value that the caller wants us to.
19456 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19459 app.adjType = "cch-empty";
19462 // Examine all activities if not already foreground.
19463 if (!foregroundActivities && activitiesSize > 0) {
19464 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19465 for (int j = 0; j < activitiesSize; j++) {
19466 final ActivityRecord r = app.activities.get(j);
19467 if (r.app != app) {
19468 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19469 + " instead of expected " + app);
19470 if (r.app == null || (r.app.uid == app.uid)) {
19471 // Only fix things up when they look sane
19478 // App has a visible activity; only upgrade adjustment.
19479 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19480 adj = ProcessList.VISIBLE_APP_ADJ;
19481 app.adjType = "visible";
19483 if (procState > PROCESS_STATE_CUR_TOP) {
19484 procState = PROCESS_STATE_CUR_TOP;
19486 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19487 app.cached = false;
19489 foregroundActivities = true;
19490 if (r.task != null && minLayer > 0) {
19491 final int layer = r.task.mLayerRank;
19492 if (layer >= 0 && minLayer > layer) {
19497 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19498 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19499 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19500 app.adjType = "pausing";
19502 if (procState > PROCESS_STATE_CUR_TOP) {
19503 procState = PROCESS_STATE_CUR_TOP;
19505 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19506 app.cached = false;
19508 foregroundActivities = true;
19509 } else if (r.state == ActivityState.STOPPING) {
19510 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19511 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19512 app.adjType = "stopping";
19514 // For the process state, we will at this point consider the
19515 // process to be cached. It will be cached either as an activity
19516 // or empty depending on whether the activity is finishing. We do
19517 // this so that we can treat the process as cached for purposes of
19518 // memory trimming (determing current memory level, trim command to
19519 // send to process) since there can be an arbitrary number of stopping
19520 // processes and they should soon all go into the cached state.
19521 if (!r.finishing) {
19522 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19523 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19526 app.cached = false;
19528 foregroundActivities = true;
19530 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19531 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19532 app.adjType = "cch-act";
19536 if (adj == ProcessList.VISIBLE_APP_ADJ) {
19541 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19542 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19543 if (app.foregroundServices) {
19544 // The user is aware of this app, so make it visible.
19545 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19546 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19547 app.cached = false;
19548 app.adjType = "fg-service";
19549 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19550 } else if (app.forcingToForeground != null) {
19551 // The user is aware of this app, so make it visible.
19552 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19553 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19554 app.cached = false;
19555 app.adjType = "force-fg";
19556 app.adjSource = app.forcingToForeground;
19557 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19561 if (app == mHeavyWeightProcess) {
19562 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19563 // We don't want to kill the current heavy-weight process.
19564 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19565 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19566 app.cached = false;
19567 app.adjType = "heavy";
19569 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19570 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19574 if (app == mHomeProcess) {
19575 if (adj > ProcessList.HOME_APP_ADJ) {
19576 // This process is hosting what we currently consider to be the
19577 // home app, so we don't want to let it go into the background.
19578 adj = ProcessList.HOME_APP_ADJ;
19579 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19580 app.cached = false;
19581 app.adjType = "home";
19583 if (procState > ActivityManager.PROCESS_STATE_HOME) {
19584 procState = ActivityManager.PROCESS_STATE_HOME;
19588 if (app == mPreviousProcess && app.activities.size() > 0) {
19589 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19590 // This was the previous process that showed UI to the user.
19591 // We want to try to keep it around more aggressively, to give
19592 // a good experience around switching between two apps.
19593 adj = ProcessList.PREVIOUS_APP_ADJ;
19594 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19595 app.cached = false;
19596 app.adjType = "previous";
19598 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19599 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19603 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19604 + " reason=" + app.adjType);
19606 // By default, we use the computed adjustment. It may be changed if
19607 // there are applications dependent on our services or providers, but
19608 // this gives us a baseline and makes sure we don't get into an
19609 // infinite recursion.
19610 app.adjSeq = mAdjSeq;
19611 app.curRawAdj = adj;
19612 app.hasStartedServices = false;
19614 if (mBackupTarget != null && app == mBackupTarget.app) {
19615 // If possible we want to avoid killing apps while they're being backed up
19616 if (adj > ProcessList.BACKUP_APP_ADJ) {
19617 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19618 adj = ProcessList.BACKUP_APP_ADJ;
19619 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19620 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19622 app.adjType = "backup";
19623 app.cached = false;
19625 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19626 procState = ActivityManager.PROCESS_STATE_BACKUP;
19630 boolean mayBeTop = false;
19632 for (int is = app.services.size()-1;
19633 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19634 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19635 || procState > ActivityManager.PROCESS_STATE_TOP);
19637 ServiceRecord s = app.services.valueAt(is);
19638 if (s.startRequested) {
19639 app.hasStartedServices = true;
19640 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19641 procState = ActivityManager.PROCESS_STATE_SERVICE;
19643 if (app.hasShownUi && app != mHomeProcess) {
19644 // If this process has shown some UI, let it immediately
19645 // go to the LRU list because it may be pretty heavy with
19646 // UI stuff. We'll tag it with a label just to help
19647 // debug and understand what is going on.
19648 if (adj > ProcessList.SERVICE_ADJ) {
19649 app.adjType = "cch-started-ui-services";
19652 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19653 // This service has seen some activity within
19654 // recent memory, so we will keep its process ahead
19655 // of the background processes.
19656 if (adj > ProcessList.SERVICE_ADJ) {
19657 adj = ProcessList.SERVICE_ADJ;
19658 app.adjType = "started-services";
19659 app.cached = false;
19662 // If we have let the service slide into the background
19663 // state, still have some text describing what it is doing
19664 // even though the service no longer has an impact.
19665 if (adj > ProcessList.SERVICE_ADJ) {
19666 app.adjType = "cch-started-services";
19671 for (int conni = s.connections.size()-1;
19672 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19673 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19674 || procState > ActivityManager.PROCESS_STATE_TOP);
19676 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19678 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19679 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19680 || procState > ActivityManager.PROCESS_STATE_TOP);
19682 // XXX should compute this based on the max of
19683 // all connected clients.
19684 ConnectionRecord cr = clist.get(i);
19685 if (cr.binding.client == app) {
19686 // Binding to ourself is not interesting.
19690 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19691 ProcessRecord client = cr.binding.client;
19692 int clientAdj = computeOomAdjLocked(client, cachedAdj,
19693 TOP_APP, doingAll, now);
19694 int clientProcState = client.curProcState;
19695 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19696 // If the other app is cached for any reason, for purposes here
19697 // we are going to consider it empty. The specific cached state
19698 // doesn't propagate except under certain conditions.
19699 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19701 String adjType = null;
19702 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19703 // Not doing bind OOM management, so treat
19704 // this guy more like a started service.
19705 if (app.hasShownUi && app != mHomeProcess) {
19706 // If this process has shown some UI, let it immediately
19707 // go to the LRU list because it may be pretty heavy with
19708 // UI stuff. We'll tag it with a label just to help
19709 // debug and understand what is going on.
19710 if (adj > clientAdj) {
19711 adjType = "cch-bound-ui-services";
19713 app.cached = false;
19715 clientProcState = procState;
19717 if (now >= (s.lastActivity
19718 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19719 // This service has not seen activity within
19720 // recent memory, so allow it to drop to the
19721 // LRU list if there is no other reason to keep
19722 // it around. We'll also tag it with a label just
19723 // to help debug and undertand what is going on.
19724 if (adj > clientAdj) {
19725 adjType = "cch-bound-services";
19731 if (adj > clientAdj) {
19732 // If this process has recently shown UI, and
19733 // the process that is binding to it is less
19734 // important than being visible, then we don't
19735 // care about the binding as much as we care
19736 // about letting this process get into the LRU
19737 // list to be killed and restarted if needed for
19739 if (app.hasShownUi && app != mHomeProcess
19740 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19741 adjType = "cch-bound-ui-services";
19743 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19744 |Context.BIND_IMPORTANT)) != 0) {
19745 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19746 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19747 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19748 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19749 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19750 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19751 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19754 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19755 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19758 if (!client.cached) {
19759 app.cached = false;
19761 adjType = "service";
19764 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19765 // This will treat important bound services identically to
19766 // the top app, which may behave differently than generic
19767 // foreground work.
19768 if (client.curSchedGroup > schedGroup) {
19769 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19770 schedGroup = client.curSchedGroup;
19772 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19775 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19776 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19777 // Special handling of clients who are in the top state.
19778 // We *may* want to consider this process to be in the
19779 // top state as well, but only if there is not another
19780 // reason for it to be running. Being on the top is a
19781 // special state, meaning you are specifically running
19782 // for the current top app. If the process is already
19783 // running in the background for some other reason, it
19784 // is more important to continue considering it to be
19785 // in the background state.
19787 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19789 // Special handling for above-top states (persistent
19790 // processes). These should not bring the current process
19791 // into the top state, since they are not on top. Instead
19792 // give them the best state after that.
19793 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19795 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19796 } else if (mWakefulness
19797 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19798 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19801 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19804 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19809 if (clientProcState <
19810 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19812 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19815 if (procState > clientProcState) {
19816 procState = clientProcState;
19818 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19819 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19820 app.pendingUiClean = true;
19822 if (adjType != null) {
19823 app.adjType = adjType;
19824 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19825 .REASON_SERVICE_IN_USE;
19826 app.adjSource = cr.binding.client;
19827 app.adjSourceProcState = clientProcState;
19828 app.adjTarget = s.name;
19831 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19832 app.treatLikeActivity = true;
19834 final ActivityRecord a = cr.activity;
19835 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19836 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19837 (a.visible || a.state == ActivityState.RESUMED ||
19838 a.state == ActivityState.PAUSING)) {
19839 adj = ProcessList.FOREGROUND_APP_ADJ;
19840 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19841 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19842 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19844 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19847 app.cached = false;
19848 app.adjType = "service";
19849 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19850 .REASON_SERVICE_IN_USE;
19852 app.adjSourceProcState = procState;
19853 app.adjTarget = s.name;
19860 for (int provi = app.pubProviders.size()-1;
19861 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19862 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19863 || procState > ActivityManager.PROCESS_STATE_TOP);
19865 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19866 for (int i = cpr.connections.size()-1;
19867 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19868 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19869 || procState > ActivityManager.PROCESS_STATE_TOP);
19871 ContentProviderConnection conn = cpr.connections.get(i);
19872 ProcessRecord client = conn.client;
19873 if (client == app) {
19874 // Being our own client is not interesting.
19877 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19878 int clientProcState = client.curProcState;
19879 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19880 // If the other app is cached for any reason, for purposes here
19881 // we are going to consider it empty.
19882 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19884 if (adj > clientAdj) {
19885 if (app.hasShownUi && app != mHomeProcess
19886 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19887 app.adjType = "cch-ui-provider";
19889 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19890 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19891 app.adjType = "provider";
19893 app.cached &= client.cached;
19894 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19895 .REASON_PROVIDER_IN_USE;
19896 app.adjSource = client;
19897 app.adjSourceProcState = clientProcState;
19898 app.adjTarget = cpr.name;
19900 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19901 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19902 // Special handling of clients who are in the top state.
19903 // We *may* want to consider this process to be in the
19904 // top state as well, but only if there is not another
19905 // reason for it to be running. Being on the top is a
19906 // special state, meaning you are specifically running
19907 // for the current top app. If the process is already
19908 // running in the background for some other reason, it
19909 // is more important to continue considering it to be
19910 // in the background state.
19912 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19914 // Special handling for above-top states (persistent
19915 // processes). These should not bring the current process
19916 // into the top state, since they are not on top. Instead
19917 // give them the best state after that.
19919 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19922 if (procState > clientProcState) {
19923 procState = clientProcState;
19925 if (client.curSchedGroup > schedGroup) {
19926 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19929 // If the provider has external (non-framework) process
19930 // dependencies, ensure that its adjustment is at least
19931 // FOREGROUND_APP_ADJ.
19932 if (cpr.hasExternalProcessHandles()) {
19933 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19934 adj = ProcessList.FOREGROUND_APP_ADJ;
19935 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19936 app.cached = false;
19937 app.adjType = "provider";
19938 app.adjTarget = cpr.name;
19940 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19941 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19946 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19947 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19948 adj = ProcessList.PREVIOUS_APP_ADJ;
19949 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19950 app.cached = false;
19951 app.adjType = "provider";
19953 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19954 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19958 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19959 // A client of one of our services or providers is in the top state. We
19960 // *may* want to be in the top state, but not if we are already running in
19961 // the background for some other reason. For the decision here, we are going
19962 // to pick out a few specific states that we want to remain in when a client
19963 // is top (states that tend to be longer-term) and otherwise allow it to go
19964 // to the top state.
19965 switch (procState) {
19966 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19967 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19968 case ActivityManager.PROCESS_STATE_SERVICE:
19969 // These all are longer-term states, so pull them up to the top
19970 // of the background states, but not all the way to the top state.
19971 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19974 // Otherwise, top is a better choice, so take it.
19975 procState = ActivityManager.PROCESS_STATE_TOP;
19980 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19981 if (app.hasClientActivities) {
19982 // This is a cached process, but with client activities. Mark it so.
19983 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19984 app.adjType = "cch-client-act";
19985 } else if (app.treatLikeActivity) {
19986 // This is a cached process, but somebody wants us to treat it like it has
19987 // an activity, okay!
19988 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19989 app.adjType = "cch-as-act";
19993 if (adj == ProcessList.SERVICE_ADJ) {
19995 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19996 mNewNumServiceProcs++;
19997 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19998 if (!app.serviceb) {
19999 // This service isn't far enough down on the LRU list to
20000 // normally be a B service, but if we are low on RAM and it
20001 // is large we want to force it down since we would prefer to
20002 // keep launcher over it.
20003 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20004 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20005 app.serviceHighRam = true;
20006 app.serviceb = true;
20007 //Slog.i(TAG, "ADJ " + app + " high ram!");
20009 mNewNumAServiceProcs++;
20010 //Slog.i(TAG, "ADJ " + app + " not high ram!");
20013 app.serviceHighRam = false;
20016 if (app.serviceb) {
20017 adj = ProcessList.SERVICE_B_ADJ;
20021 app.curRawAdj = adj;
20023 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20024 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20025 if (adj > app.maxAdj) {
20027 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20028 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20032 // Do final modification to adj. Everything we do between here and applying
20033 // the final setAdj must be done in this function, because we will also use
20034 // it when computing the final cached adj later. Note that we don't need to
20035 // worry about this for max adj above, since max adj will always be used to
20036 // keep it out of the cached vaues.
20037 app.curAdj = app.modifyRawOomAdj(adj);
20038 app.curSchedGroup = schedGroup;
20039 app.curProcState = procState;
20040 app.foregroundActivities = foregroundActivities;
20042 return app.curRawAdj;
20046 * Record new PSS sample for a process.
20048 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20050 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20052 proc.lastPssTime = now;
20053 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20054 if (DEBUG_PSS) Slog.d(TAG_PSS,
20055 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20056 + " state=" + ProcessList.makeProcStateString(procState));
20057 if (proc.initialIdlePss == 0) {
20058 proc.initialIdlePss = pss;
20060 proc.lastPss = pss;
20061 proc.lastSwapPss = swapPss;
20062 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20063 proc.lastCachedPss = pss;
20064 proc.lastCachedSwapPss = swapPss;
20067 final SparseArray<Pair<Long, String>> watchUids
20068 = mMemWatchProcesses.getMap().get(proc.processName);
20070 if (watchUids != null) {
20071 Pair<Long, String> val = watchUids.get(proc.uid);
20073 val = watchUids.get(0);
20079 if (check != null) {
20080 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20081 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20082 if (!isDebuggable) {
20083 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20084 isDebuggable = true;
20087 if (isDebuggable) {
20088 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20089 final ProcessRecord myProc = proc;
20090 final File heapdumpFile = DumpHeapProvider.getJavaFile();
20091 mMemWatchDumpProcName = proc.processName;
20092 mMemWatchDumpFile = heapdumpFile.toString();
20093 mMemWatchDumpPid = proc.pid;
20094 mMemWatchDumpUid = proc.uid;
20095 BackgroundThread.getHandler().post(new Runnable() {
20097 public void run() {
20098 revokeUriPermission(ActivityThread.currentActivityThread()
20099 .getApplicationThread(),
20100 DumpHeapActivity.JAVA_URI,
20101 Intent.FLAG_GRANT_READ_URI_PERMISSION
20102 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20103 UserHandle.myUserId());
20104 ParcelFileDescriptor fd = null;
20106 heapdumpFile.delete();
20107 fd = ParcelFileDescriptor.open(heapdumpFile,
20108 ParcelFileDescriptor.MODE_CREATE |
20109 ParcelFileDescriptor.MODE_TRUNCATE |
20110 ParcelFileDescriptor.MODE_WRITE_ONLY |
20111 ParcelFileDescriptor.MODE_APPEND);
20112 IApplicationThread thread = myProc.thread;
20113 if (thread != null) {
20115 if (DEBUG_PSS) Slog.d(TAG_PSS,
20116 "Requesting dump heap from "
20117 + myProc + " to " + heapdumpFile);
20118 thread.dumpHeap(true, heapdumpFile.toString(), fd);
20119 } catch (RemoteException e) {
20122 } catch (FileNotFoundException e) {
20123 e.printStackTrace();
20128 } catch (IOException e) {
20135 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20136 + ", but debugging not enabled");
20143 * Schedule PSS collection of a process.
20145 void requestPssLocked(ProcessRecord proc, int procState) {
20146 if (mPendingPssProcesses.contains(proc)) {
20149 if (mPendingPssProcesses.size() == 0) {
20150 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20152 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20153 proc.pssProcState = procState;
20154 mPendingPssProcesses.add(proc);
20158 * Schedule PSS collection of all processes.
20160 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20162 if (now < (mLastFullPssTime +
20163 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20167 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
20168 mLastFullPssTime = now;
20169 mFullPssPending = true;
20170 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20171 mPendingPssProcesses.clear();
20172 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20173 ProcessRecord app = mLruProcesses.get(i);
20174 if (app.thread == null
20175 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20178 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20179 app.pssProcState = app.setProcState;
20180 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20181 mTestPssMode, isSleepingLocked(), now);
20182 mPendingPssProcesses.add(app);
20185 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20188 public void setTestPssMode(boolean enabled) {
20189 synchronized (this) {
20190 mTestPssMode = enabled;
20192 // Whenever we enable the mode, we want to take a snapshot all of current
20193 // process mem use.
20194 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20200 * Ask a given process to GC right now.
20202 final void performAppGcLocked(ProcessRecord app) {
20204 app.lastRequestedGc = SystemClock.uptimeMillis();
20205 if (app.thread != null) {
20206 if (app.reportLowMemory) {
20207 app.reportLowMemory = false;
20208 app.thread.scheduleLowMemory();
20210 app.thread.processInBackground();
20213 } catch (Exception e) {
20219 * Returns true if things are idle enough to perform GCs.
20221 private final boolean canGcNowLocked() {
20222 boolean processingBroadcasts = false;
20223 for (BroadcastQueue q : mBroadcastQueues) {
20224 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20225 processingBroadcasts = true;
20228 return !processingBroadcasts
20229 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20233 * Perform GCs on all processes that are waiting for it, but only
20234 * if things are idle.
20236 final void performAppGcsLocked() {
20237 final int N = mProcessesToGc.size();
20241 if (canGcNowLocked()) {
20242 while (mProcessesToGc.size() > 0) {
20243 ProcessRecord proc = mProcessesToGc.remove(0);
20244 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20245 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20246 <= SystemClock.uptimeMillis()) {
20247 // To avoid spamming the system, we will GC processes one
20248 // at a time, waiting a few seconds between each.
20249 performAppGcLocked(proc);
20250 scheduleAppGcsLocked();
20253 // It hasn't been long enough since we last GCed this
20254 // process... put it in the list to wait for its time.
20255 addProcessToGcListLocked(proc);
20261 scheduleAppGcsLocked();
20266 * If all looks good, perform GCs on all processes waiting for them.
20268 final void performAppGcsIfAppropriateLocked() {
20269 if (canGcNowLocked()) {
20270 performAppGcsLocked();
20273 // Still not idle, wait some more.
20274 scheduleAppGcsLocked();
20278 * Schedule the execution of all pending app GCs.
20280 final void scheduleAppGcsLocked() {
20281 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20283 if (mProcessesToGc.size() > 0) {
20284 // Schedule a GC for the time to the next process.
20285 ProcessRecord proc = mProcessesToGc.get(0);
20286 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20288 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20289 long now = SystemClock.uptimeMillis();
20290 if (when < (now+GC_TIMEOUT)) {
20291 when = now + GC_TIMEOUT;
20293 mHandler.sendMessageAtTime(msg, when);
20298 * Add a process to the array of processes waiting to be GCed. Keeps the
20299 * list in sorted order by the last GC time. The process can't already be
20302 final void addProcessToGcListLocked(ProcessRecord proc) {
20303 boolean added = false;
20304 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20305 if (mProcessesToGc.get(i).lastRequestedGc <
20306 proc.lastRequestedGc) {
20308 mProcessesToGc.add(i+1, proc);
20313 mProcessesToGc.add(0, proc);
20318 * Set up to ask a process to GC itself. This will either do it
20319 * immediately, or put it on the list of processes to gc the next
20320 * time things are idle.
20322 final void scheduleAppGcLocked(ProcessRecord app) {
20323 long now = SystemClock.uptimeMillis();
20324 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20327 if (!mProcessesToGc.contains(app)) {
20328 addProcessToGcListLocked(app);
20329 scheduleAppGcsLocked();
20333 final void checkExcessivePowerUsageLocked(boolean doKills) {
20334 updateCpuStatsNow();
20336 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20337 boolean doWakeKills = doKills;
20338 boolean doCpuKills = doKills;
20339 if (mLastPowerCheckRealtime == 0) {
20340 doWakeKills = false;
20342 if (mLastPowerCheckUptime == 0) {
20343 doCpuKills = false;
20345 if (stats.isScreenOn()) {
20346 doWakeKills = false;
20348 final long curRealtime = SystemClock.elapsedRealtime();
20349 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20350 final long curUptime = SystemClock.uptimeMillis();
20351 final long uptimeSince = curUptime - mLastPowerCheckUptime;
20352 mLastPowerCheckRealtime = curRealtime;
20353 mLastPowerCheckUptime = curUptime;
20354 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20355 doWakeKills = false;
20357 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20358 doCpuKills = false;
20360 int i = mLruProcesses.size();
20363 ProcessRecord app = mLruProcesses.get(i);
20364 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20366 synchronized (stats) {
20367 wtime = stats.getProcessWakeTime(app.info.uid,
20368 app.pid, curRealtime);
20370 long wtimeUsed = wtime - app.lastWakeTime;
20371 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20373 StringBuilder sb = new StringBuilder(128);
20374 sb.append("Wake for ");
20375 app.toShortString(sb);
20376 sb.append(": over ");
20377 TimeUtils.formatDuration(realtimeSince, sb);
20378 sb.append(" used ");
20379 TimeUtils.formatDuration(wtimeUsed, sb);
20381 sb.append((wtimeUsed*100)/realtimeSince);
20383 Slog.i(TAG_POWER, sb.toString());
20385 sb.append("CPU for ");
20386 app.toShortString(sb);
20387 sb.append(": over ");
20388 TimeUtils.formatDuration(uptimeSince, sb);
20389 sb.append(" used ");
20390 TimeUtils.formatDuration(cputimeUsed, sb);
20392 sb.append((cputimeUsed*100)/uptimeSince);
20394 Slog.i(TAG_POWER, sb.toString());
20396 // If a process has held a wake lock for more
20397 // than 50% of the time during this period,
20398 // that sounds bad. Kill!
20399 if (doWakeKills && realtimeSince > 0
20400 && ((wtimeUsed*100)/realtimeSince) >= 50) {
20401 synchronized (stats) {
20402 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20403 realtimeSince, wtimeUsed);
20405 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20406 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20407 } else if (doCpuKills && uptimeSince > 0
20408 && ((cputimeUsed*100)/uptimeSince) >= 25) {
20409 synchronized (stats) {
20410 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20411 uptimeSince, cputimeUsed);
20413 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20414 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20416 app.lastWakeTime = wtime;
20417 app.lastCpuTime = app.curCpuTime;
20423 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20425 boolean success = true;
20427 if (app.curRawAdj != app.setRawAdj) {
20428 app.setRawAdj = app.curRawAdj;
20433 if (app.curAdj != app.setAdj) {
20434 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20435 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20436 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20438 app.setAdj = app.curAdj;
20439 app.verifiedAdj = ProcessList.INVALID_ADJ;
20442 if (app.setSchedGroup != app.curSchedGroup) {
20443 int oldSchedGroup = app.setSchedGroup;
20444 app.setSchedGroup = app.curSchedGroup;
20445 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20446 "Setting sched group of " + app.processName
20447 + " to " + app.curSchedGroup);
20448 if (app.waitingToKill != null && app.curReceiver == null
20449 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20450 app.kill(app.waitingToKill, true);
20454 switch (app.curSchedGroup) {
20455 case ProcessList.SCHED_GROUP_BACKGROUND:
20456 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20458 case ProcessList.SCHED_GROUP_TOP_APP:
20459 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20460 processGroup = Process.THREAD_GROUP_TOP_APP;
20463 processGroup = Process.THREAD_GROUP_DEFAULT;
20466 long oldId = Binder.clearCallingIdentity();
20468 Process.setProcessGroup(app.pid, processGroup);
20469 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20470 // do nothing if we already switched to RT
20471 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20472 // Switch VR thread for app to SCHED_FIFO
20473 if (mInVrMode && app.vrThreadTid != 0) {
20475 Process.setThreadScheduler(app.vrThreadTid,
20476 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20477 } catch (IllegalArgumentException e) {
20478 // thread died, ignore
20481 if (mUseFifoUiScheduling) {
20482 // Switch UI pipeline for app to SCHED_FIFO
20483 app.savedPriority = Process.getThreadPriority(app.pid);
20485 Process.setThreadScheduler(app.pid,
20486 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20487 } catch (IllegalArgumentException e) {
20488 // thread died, ignore
20490 if (app.renderThreadTid != 0) {
20492 Process.setThreadScheduler(app.renderThreadTid,
20493 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20494 } catch (IllegalArgumentException e) {
20495 // thread died, ignore
20497 if (DEBUG_OOM_ADJ) {
20498 Slog.d("UI_FIFO", "Set RenderThread (TID " +
20499 app.renderThreadTid + ") to FIFO");
20502 if (DEBUG_OOM_ADJ) {
20503 Slog.d("UI_FIFO", "Not setting RenderThread TID");
20507 // Boost priority for top app UI and render threads
20508 Process.setThreadPriority(app.pid, -10);
20509 if (app.renderThreadTid != 0) {
20511 Process.setThreadPriority(app.renderThreadTid, -10);
20512 } catch (IllegalArgumentException e) {
20513 // thread died, ignore
20518 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20519 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20520 // Reset VR thread to SCHED_OTHER
20521 // Safe to do even if we're not in VR mode
20522 if (app.vrThreadTid != 0) {
20523 Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20525 if (mUseFifoUiScheduling) {
20526 // Reset UI pipeline to SCHED_OTHER
20527 Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20528 Process.setThreadPriority(app.pid, app.savedPriority);
20529 if (app.renderThreadTid != 0) {
20530 Process.setThreadScheduler(app.renderThreadTid,
20531 Process.SCHED_OTHER, 0);
20532 Process.setThreadPriority(app.renderThreadTid, -4);
20535 // Reset priority for top app UI and render threads
20536 Process.setThreadPriority(app.pid, 0);
20537 if (app.renderThreadTid != 0) {
20538 Process.setThreadPriority(app.renderThreadTid, 0);
20542 } catch (Exception e) {
20543 Slog.w(TAG, "Failed setting process group of " + app.pid
20544 + " to " + app.curSchedGroup);
20545 e.printStackTrace();
20547 Binder.restoreCallingIdentity(oldId);
20551 if (app.repForegroundActivities != app.foregroundActivities) {
20552 app.repForegroundActivities = app.foregroundActivities;
20553 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20555 if (app.repProcState != app.curProcState) {
20556 app.repProcState = app.curProcState;
20557 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20558 if (app.thread != null) {
20561 //RuntimeException h = new RuntimeException("here");
20562 Slog.i(TAG, "Sending new process state " + app.repProcState
20563 + " to " + app /*, h*/);
20565 app.thread.setProcessState(app.repProcState);
20566 } catch (RemoteException e) {
20570 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20571 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20572 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20573 // Experimental code to more aggressively collect pss while
20574 // running test... the problem is that this tends to collect
20575 // the data right when a process is transitioning between process
20576 // states, which well tend to give noisy data.
20577 long start = SystemClock.uptimeMillis();
20578 long pss = Debug.getPss(app.pid, mTmpLong, null);
20579 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20580 mPendingPssProcesses.remove(app);
20581 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20582 + " to " + app.curProcState + ": "
20583 + (SystemClock.uptimeMillis()-start) + "ms");
20585 app.lastStateTime = now;
20586 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20587 mTestPssMode, isSleepingLocked(), now);
20588 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20589 + ProcessList.makeProcStateString(app.setProcState) + " to "
20590 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20591 + (app.nextPssTime-now) + ": " + app);
20593 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20594 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20596 requestPssLocked(app, app.setProcState);
20597 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20598 mTestPssMode, isSleepingLocked(), now);
20599 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20600 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20602 if (app.setProcState != app.curProcState) {
20603 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20604 "Proc state change of " + app.processName
20605 + " to " + app.curProcState);
20606 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20607 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20608 if (setImportant && !curImportant) {
20609 // This app is no longer something we consider important enough to allow to
20610 // use arbitrary amounts of battery power. Note
20611 // its current wake lock time to later know to kill it if
20612 // it is not behaving well.
20613 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20614 synchronized (stats) {
20615 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20616 app.pid, nowElapsed);
20618 app.lastCpuTime = app.curCpuTime;
20621 // Inform UsageStats of important process state change
20622 // Must be called before updating setProcState
20623 maybeUpdateUsageStatsLocked(app, nowElapsed);
20625 app.setProcState = app.curProcState;
20626 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20627 app.notCachedSinceIdle = false;
20630 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20632 app.procStateChanged = true;
20634 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20635 > USAGE_STATS_INTERACTION_INTERVAL) {
20636 // For apps that sit around for a long time in the interactive state, we need
20637 // to report this at least once a day so they don't go idle.
20638 maybeUpdateUsageStatsLocked(app, nowElapsed);
20641 if (changes != 0) {
20642 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20643 "Changes in " + app + ": " + changes);
20644 int i = mPendingProcessChanges.size()-1;
20645 ProcessChangeItem item = null;
20647 item = mPendingProcessChanges.get(i);
20648 if (item.pid == app.pid) {
20649 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20650 "Re-using existing item: " + item);
20656 // No existing item in pending changes; need a new one.
20657 final int NA = mAvailProcessChanges.size();
20659 item = mAvailProcessChanges.remove(NA-1);
20660 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20661 "Retrieving available item: " + item);
20663 item = new ProcessChangeItem();
20664 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20665 "Allocating new item: " + item);
20668 item.pid = app.pid;
20669 item.uid = app.info.uid;
20670 if (mPendingProcessChanges.size() == 0) {
20671 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20672 "*** Enqueueing dispatch processes changed!");
20673 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20675 mPendingProcessChanges.add(item);
20677 item.changes |= changes;
20678 item.processState = app.repProcState;
20679 item.foregroundActivities = app.repForegroundActivities;
20680 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20681 "Item " + Integer.toHexString(System.identityHashCode(item))
20682 + " " + app.toShortString() + ": changes=" + item.changes
20683 + " procState=" + item.processState
20684 + " foreground=" + item.foregroundActivities
20685 + " type=" + app.adjType + " source=" + app.adjSource
20686 + " target=" + app.adjTarget);
20692 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20693 final UidRecord.ChangeItem pendingChange;
20694 if (uidRec == null || uidRec.pendingChange == null) {
20695 if (mPendingUidChanges.size() == 0) {
20696 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20697 "*** Enqueueing dispatch uid changed!");
20698 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20700 final int NA = mAvailUidChanges.size();
20702 pendingChange = mAvailUidChanges.remove(NA-1);
20703 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20704 "Retrieving available item: " + pendingChange);
20706 pendingChange = new UidRecord.ChangeItem();
20707 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20708 "Allocating new item: " + pendingChange);
20710 if (uidRec != null) {
20711 uidRec.pendingChange = pendingChange;
20712 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20713 // If this uid is going away, and we haven't yet reported it is gone,
20715 change = UidRecord.CHANGE_GONE_IDLE;
20717 } else if (uid < 0) {
20718 throw new IllegalArgumentException("No UidRecord or uid");
20720 pendingChange.uidRecord = uidRec;
20721 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20722 mPendingUidChanges.add(pendingChange);
20724 pendingChange = uidRec.pendingChange;
20725 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20726 change = UidRecord.CHANGE_GONE_IDLE;
20729 pendingChange.change = change;
20730 pendingChange.processState = uidRec != null
20731 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20734 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20735 String authority) {
20736 if (app == null) return;
20737 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20738 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20739 if (userState == null) return;
20740 final long now = SystemClock.elapsedRealtime();
20741 Long lastReported = userState.mProviderLastReportedFg.get(authority);
20742 if (lastReported == null || lastReported < now - 60 * 1000L) {
20743 if (mSystemReady) {
20744 // Cannot touch the user stats if not system ready
20745 mUsageStatsService.reportContentProviderUsage(
20746 authority, providerPkgName, app.userId);
20748 userState.mProviderLastReportedFg.put(authority, now);
20753 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20754 if (DEBUG_USAGE_STATS) {
20755 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20756 + "] state changes: old = " + app.setProcState + ", new = "
20757 + app.curProcState);
20759 if (mUsageStatsService == null) {
20762 boolean isInteraction;
20763 // To avoid some abuse patterns, we are going to be careful about what we consider
20764 // to be an app interaction. Being the top activity doesn't count while the display
20765 // is sleeping, nor do short foreground services.
20766 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20767 isInteraction = true;
20768 app.fgInteractionTime = 0;
20769 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20770 if (app.fgInteractionTime == 0) {
20771 app.fgInteractionTime = nowElapsed;
20772 isInteraction = false;
20774 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20777 // If the app was being forced to the foreground, by say a Toast, then
20778 // no need to treat it as an interaction
20779 isInteraction = app.forcingToForeground == null
20780 && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20781 app.fgInteractionTime = 0;
20783 if (isInteraction && (!app.reportedInteraction
20784 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20785 app.interactionEventTime = nowElapsed;
20786 String[] packages = app.getPackageList();
20787 if (packages != null) {
20788 for (int i = 0; i < packages.length; i++) {
20789 mUsageStatsService.reportEvent(packages[i], app.userId,
20790 UsageEvents.Event.SYSTEM_INTERACTION);
20794 app.reportedInteraction = isInteraction;
20795 if (!isInteraction) {
20796 app.interactionEventTime = 0;
20800 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20801 if (proc.thread != null) {
20802 if (proc.baseProcessTracker != null) {
20803 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20808 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20809 ProcessRecord TOP_APP, boolean doingAll, long now) {
20810 if (app.thread == null) {
20814 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20816 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20819 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20821 if (isForeground != proc.foregroundServices) {
20822 proc.foregroundServices = isForeground;
20823 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20825 if (isForeground) {
20826 if (curProcs == null) {
20827 curProcs = new ArrayList<ProcessRecord>();
20828 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20830 if (!curProcs.contains(proc)) {
20831 curProcs.add(proc);
20832 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20833 proc.info.packageName, proc.info.uid);
20836 if (curProcs != null) {
20837 if (curProcs.remove(proc)) {
20838 mBatteryStatsService.noteEvent(
20839 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20840 proc.info.packageName, proc.info.uid);
20841 if (curProcs.size() <= 0) {
20842 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20848 updateOomAdjLocked();
20853 private final ActivityRecord resumedAppLocked() {
20854 ActivityRecord act = mStackSupervisor.resumedAppLocked();
20858 pkg = act.packageName;
20859 uid = act.info.applicationInfo.uid;
20864 // Has the UID or resumed package name changed?
20865 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20866 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20867 if (mCurResumedPackage != null) {
20868 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20869 mCurResumedPackage, mCurResumedUid);
20871 mCurResumedPackage = pkg;
20872 mCurResumedUid = uid;
20873 if (mCurResumedPackage != null) {
20874 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20875 mCurResumedPackage, mCurResumedUid);
20881 final boolean updateOomAdjLocked(ProcessRecord app) {
20882 final ActivityRecord TOP_ACT = resumedAppLocked();
20883 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20884 final boolean wasCached = app.cached;
20888 // This is the desired cached adjusment we want to tell it to use.
20889 // If our app is currently cached, we know it, and that is it. Otherwise,
20890 // we don't know it yet, and it needs to now be cached we will then
20891 // need to do a complete oom adj.
20892 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20893 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20894 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20895 SystemClock.uptimeMillis());
20896 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20897 // Changed to/from cached state, so apps after it in the LRU
20898 // list may also be changed.
20899 updateOomAdjLocked();
20904 final void updateOomAdjLocked() {
20905 final ActivityRecord TOP_ACT = resumedAppLocked();
20906 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20907 final long now = SystemClock.uptimeMillis();
20908 final long nowElapsed = SystemClock.elapsedRealtime();
20909 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20910 final int N = mLruProcesses.size();
20913 RuntimeException e = new RuntimeException();
20914 e.fillInStackTrace();
20915 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20918 // Reset state in all uid records.
20919 for (int i=mActiveUids.size()-1; i>=0; i--) {
20920 final UidRecord uidRec = mActiveUids.valueAt(i);
20921 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20922 "Starting update of " + uidRec);
20926 mStackSupervisor.rankTaskLayersIfNeeded();
20929 mNewNumServiceProcs = 0;
20930 mNewNumAServiceProcs = 0;
20932 final int emptyProcessLimit;
20933 final int cachedProcessLimit;
20934 if (mProcessLimit <= 0) {
20935 emptyProcessLimit = cachedProcessLimit = 0;
20936 } else if (mProcessLimit == 1) {
20937 emptyProcessLimit = 1;
20938 cachedProcessLimit = 0;
20940 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20941 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20944 // Let's determine how many processes we have running vs.
20945 // how many slots we have for background processes; we may want
20946 // to put multiple processes in a slot of there are enough of
20948 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20949 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20950 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20951 if (numEmptyProcs > cachedProcessLimit) {
20952 // If there are more empty processes than our limit on cached
20953 // processes, then use the cached process limit for the factor.
20954 // This ensures that the really old empty processes get pushed
20955 // down to the bottom, so if we are running low on memory we will
20956 // have a better chance at keeping around more cached processes
20957 // instead of a gazillion empty processes.
20958 numEmptyProcs = cachedProcessLimit;
20960 int emptyFactor = numEmptyProcs/numSlots;
20961 if (emptyFactor < 1) emptyFactor = 1;
20962 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20963 if (cachedFactor < 1) cachedFactor = 1;
20964 int stepCached = 0;
20968 int numTrimming = 0;
20970 mNumNonCachedProcs = 0;
20971 mNumCachedHiddenProcs = 0;
20973 // First update the OOM adjustment for each of the
20974 // application processes based on their current state.
20975 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20976 int nextCachedAdj = curCachedAdj+1;
20977 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20978 int nextEmptyAdj = curEmptyAdj+2;
20979 for (int i=N-1; i>=0; i--) {
20980 ProcessRecord app = mLruProcesses.get(i);
20981 if (!app.killedByAm && app.thread != null) {
20982 app.procStateChanged = false;
20983 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20985 // If we haven't yet assigned the final cached adj
20986 // to the process, do that now.
20987 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20988 switch (app.curProcState) {
20989 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20990 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20991 // This process is a cached process holding activities...
20992 // assign it the next cached value for that type, and then
20993 // step that cached level.
20994 app.curRawAdj = curCachedAdj;
20995 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20996 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20997 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20999 if (curCachedAdj != nextCachedAdj) {
21001 if (stepCached >= cachedFactor) {
21003 curCachedAdj = nextCachedAdj;
21004 nextCachedAdj += 2;
21005 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21006 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21012 // For everything else, assign next empty cached process
21013 // level and bump that up. Note that this means that
21014 // long-running services that have dropped down to the
21015 // cached level will be treated as empty (since their process
21016 // state is still as a service), which is what we want.
21017 app.curRawAdj = curEmptyAdj;
21018 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21019 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21020 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21022 if (curEmptyAdj != nextEmptyAdj) {
21024 if (stepEmpty >= emptyFactor) {
21026 curEmptyAdj = nextEmptyAdj;
21028 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21029 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21037 applyOomAdjLocked(app, true, now, nowElapsed);
21039 // Count the number of process types.
21040 switch (app.curProcState) {
21041 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21042 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21043 mNumCachedHiddenProcs++;
21045 if (numCached > cachedProcessLimit) {
21046 app.kill("cached #" + numCached, true);
21049 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21050 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21051 && app.lastActivityTime < oldTime) {
21052 app.kill("empty for "
21053 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21054 / 1000) + "s", true);
21057 if (numEmpty > emptyProcessLimit) {
21058 app.kill("empty #" + numEmpty, true);
21063 mNumNonCachedProcs++;
21067 if (app.isolated && app.services.size() <= 0) {
21068 // If this is an isolated process, and there are no
21069 // services running in it, then the process is no longer
21070 // needed. We agressively kill these because we can by
21071 // definition not re-use the same process again, and it is
21072 // good to avoid having whatever code was running in them
21073 // left sitting around after no longer needed.
21074 app.kill("isolated not needed", true);
21076 // Keeping this process, update its uid.
21077 final UidRecord uidRec = app.uidRecord;
21078 if (uidRec != null && uidRec.curProcState > app.curProcState) {
21079 uidRec.curProcState = app.curProcState;
21083 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21084 && !app.killedByAm) {
21090 mNumServiceProcs = mNewNumServiceProcs;
21092 // Now determine the memory trimming level of background processes.
21093 // Unfortunately we need to start at the back of the list to do this
21094 // properly. We only do this if the number of background apps we
21095 // are managing to keep around is less than half the maximum we desire;
21096 // if we are keeping a good number around, we'll let them use whatever
21097 // memory they want.
21098 final int numCachedAndEmpty = numCached + numEmpty;
21100 if (numCached <= ProcessList.TRIM_CACHED_APPS
21101 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21102 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21103 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21104 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21105 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21107 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21110 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21112 // We always allow the memory level to go up (better). We only allow it to go
21113 // down if we are in a state where that is allowed, *and* the total number of processes
21114 // has gone down since last time.
21115 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21116 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21117 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21118 if (memFactor > mLastMemoryLevel) {
21119 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21120 memFactor = mLastMemoryLevel;
21121 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21124 if (memFactor != mLastMemoryLevel) {
21125 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21127 mLastMemoryLevel = memFactor;
21128 mLastNumProcesses = mLruProcesses.size();
21129 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21130 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21131 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21132 if (mLowRamStartTime == 0) {
21133 mLowRamStartTime = now;
21137 switch (memFactor) {
21138 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21139 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21141 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21142 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21145 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21148 int factor = numTrimming/3;
21150 if (mHomeProcess != null) minFactor++;
21151 if (mPreviousProcess != null) minFactor++;
21152 if (factor < minFactor) factor = minFactor;
21153 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21154 for (int i=N-1; i>=0; i--) {
21155 ProcessRecord app = mLruProcesses.get(i);
21156 if (allChanged || app.procStateChanged) {
21157 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21158 app.procStateChanged = false;
21160 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21161 && !app.killedByAm) {
21162 if (app.trimMemoryLevel < curLevel && app.thread != null) {
21164 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21165 "Trimming memory of " + app.processName + " to " + curLevel);
21166 app.thread.scheduleTrimMemory(curLevel);
21167 } catch (RemoteException e) {
21170 // For now we won't do this; our memory trimming seems
21171 // to be good enough at this point that destroying
21172 // activities causes more harm than good.
21173 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21174 && app != mHomeProcess && app != mPreviousProcess) {
21175 // Need to do this on its own message because the stack may not
21176 // be in a consistent state at this point.
21177 // For these apps we will also finish their activities
21178 // to help them free memory.
21179 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21183 app.trimMemoryLevel = curLevel;
21185 if (step >= factor) {
21187 switch (curLevel) {
21188 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21189 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21191 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21192 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21196 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21197 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21198 && app.thread != null) {
21200 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21201 "Trimming memory of heavy-weight " + app.processName
21202 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21203 app.thread.scheduleTrimMemory(
21204 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21205 } catch (RemoteException e) {
21208 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21210 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21211 || app.systemNoUi) && app.pendingUiClean) {
21212 // If this application is now in the background and it
21213 // had done UI, then give it the special trim level to
21214 // have it free UI resources.
21215 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21216 if (app.trimMemoryLevel < level && app.thread != null) {
21218 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21219 "Trimming memory of bg-ui " + app.processName
21221 app.thread.scheduleTrimMemory(level);
21222 } catch (RemoteException e) {
21225 app.pendingUiClean = false;
21227 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21229 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21230 "Trimming memory of fg " + app.processName
21231 + " to " + fgTrimLevel);
21232 app.thread.scheduleTrimMemory(fgTrimLevel);
21233 } catch (RemoteException e) {
21236 app.trimMemoryLevel = fgTrimLevel;
21240 if (mLowRamStartTime != 0) {
21241 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21242 mLowRamStartTime = 0;
21244 for (int i=N-1; i>=0; i--) {
21245 ProcessRecord app = mLruProcesses.get(i);
21246 if (allChanged || app.procStateChanged) {
21247 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21248 app.procStateChanged = false;
21250 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21251 || app.systemNoUi) && app.pendingUiClean) {
21252 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21253 && app.thread != null) {
21255 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21256 "Trimming memory of ui hidden " + app.processName
21257 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21258 app.thread.scheduleTrimMemory(
21259 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21260 } catch (RemoteException e) {
21263 app.pendingUiClean = false;
21265 app.trimMemoryLevel = 0;
21269 if (mAlwaysFinishActivities) {
21270 // Need to do this on its own message because the stack may not
21271 // be in a consistent state at this point.
21272 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21276 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21279 // Update from any uid changes.
21280 for (int i=mActiveUids.size()-1; i>=0; i--) {
21281 final UidRecord uidRec = mActiveUids.valueAt(i);
21282 int uidChange = UidRecord.CHANGE_PROCSTATE;
21283 if (uidRec.setProcState != uidRec.curProcState) {
21284 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21285 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21286 + " to " + uidRec.curProcState);
21287 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21288 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21289 uidRec.lastBackgroundTime = nowElapsed;
21290 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21291 // Note: the background settle time is in elapsed realtime, while
21292 // the handler time base is uptime. All this means is that we may
21293 // stop background uids later than we had intended, but that only
21294 // happens because the device was sleeping so we are okay anyway.
21295 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21300 uidChange = UidRecord.CHANGE_ACTIVE;
21301 uidRec.idle = false;
21303 uidRec.lastBackgroundTime = 0;
21305 uidRec.setProcState = uidRec.curProcState;
21306 enqueueUidChangeLocked(uidRec, -1, uidChange);
21307 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21311 if (mProcessStats.shouldWriteNowLocked(now)) {
21312 mHandler.post(new Runnable() {
21313 @Override public void run() {
21314 synchronized (ActivityManagerService.this) {
21315 mProcessStats.writeStateAsyncLocked();
21321 if (DEBUG_OOM_ADJ) {
21322 final long duration = SystemClock.uptimeMillis() - now;
21324 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21325 new RuntimeException("here").fillInStackTrace());
21327 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21332 final void idleUids() {
21333 synchronized (this) {
21334 final long nowElapsed = SystemClock.elapsedRealtime();
21335 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21337 for (int i=mActiveUids.size()-1; i>=0; i--) {
21338 final UidRecord uidRec = mActiveUids.valueAt(i);
21339 final long bgTime = uidRec.lastBackgroundTime;
21340 if (bgTime > 0 && !uidRec.idle) {
21341 if (bgTime <= maxBgTime) {
21342 uidRec.idle = true;
21343 doStopUidLocked(uidRec.uid, uidRec);
21345 if (nextTime == 0 || nextTime > bgTime) {
21351 if (nextTime > 0) {
21352 mHandler.removeMessages(IDLE_UIDS_MSG);
21353 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21354 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21359 final void runInBackgroundDisabled(int uid) {
21360 synchronized (this) {
21361 UidRecord uidRec = mActiveUids.get(uid);
21362 if (uidRec != null) {
21363 // This uid is actually running... should it be considered background now?
21365 doStopUidLocked(uidRec.uid, uidRec);
21368 // This uid isn't actually running... still send a report about it being "stopped".
21369 doStopUidLocked(uid, null);
21374 final void doStopUidLocked(int uid, final UidRecord uidRec) {
21375 mServices.stopInBackgroundLocked(uid);
21376 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21379 final void trimApplications() {
21380 synchronized (this) {
21383 // First remove any unused application processes whose package
21384 // has been removed.
21385 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21386 final ProcessRecord app = mRemovedProcesses.get(i);
21387 if (app.activities.size() == 0
21388 && app.curReceiver == null && app.services.size() == 0) {
21390 TAG, "Exiting empty application process "
21391 + app.toShortString() + " ("
21392 + (app.thread != null ? app.thread.asBinder() : null)
21394 if (app.pid > 0 && app.pid != MY_PID) {
21395 app.kill("empty", false);
21398 app.thread.scheduleExit();
21399 } catch (Exception e) {
21400 // Ignore exceptions.
21403 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21404 mRemovedProcesses.remove(i);
21406 if (app.persistent) {
21407 addAppLocked(app.info, false, null /* ABI override */);
21412 // Now update the oom adj for all processes.
21413 updateOomAdjLocked();
21417 /** This method sends the specified signal to each of the persistent apps */
21418 public void signalPersistentProcesses(int sig) throws RemoteException {
21419 if (sig != Process.SIGNAL_USR1) {
21420 throw new SecurityException("Only SIGNAL_USR1 is allowed");
21423 synchronized (this) {
21424 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21425 != PackageManager.PERMISSION_GRANTED) {
21426 throw new SecurityException("Requires permission "
21427 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21430 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21431 ProcessRecord r = mLruProcesses.get(i);
21432 if (r.thread != null && r.persistent) {
21433 Process.sendSignal(r.pid, sig);
21439 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21440 if (proc == null || proc == mProfileProc) {
21441 proc = mProfileProc;
21442 profileType = mProfileType;
21443 clearProfilerLocked();
21445 if (proc == null) {
21449 proc.thread.profilerControl(false, null, profileType);
21450 } catch (RemoteException e) {
21451 throw new IllegalStateException("Process disappeared");
21455 private void clearProfilerLocked() {
21456 if (mProfileFd != null) {
21458 mProfileFd.close();
21459 } catch (IOException e) {
21462 mProfileApp = null;
21463 mProfileProc = null;
21464 mProfileFile = null;
21466 mAutoStopProfiler = false;
21467 mSamplingInterval = 0;
21470 public boolean profileControl(String process, int userId, boolean start,
21471 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21474 synchronized (this) {
21475 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21476 // its own permission.
21477 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21478 != PackageManager.PERMISSION_GRANTED) {
21479 throw new SecurityException("Requires permission "
21480 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21483 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21484 throw new IllegalArgumentException("null profile info or fd");
21487 ProcessRecord proc = null;
21488 if (process != null) {
21489 proc = findProcessLocked(process, userId, "profileControl");
21492 if (start && (proc == null || proc.thread == null)) {
21493 throw new IllegalArgumentException("Unknown process: " + process);
21497 stopProfilerLocked(null, 0);
21498 setProfileApp(proc.info, proc.processName, profilerInfo);
21499 mProfileProc = proc;
21500 mProfileType = profileType;
21501 ParcelFileDescriptor fd = profilerInfo.profileFd;
21504 } catch (IOException e) {
21507 profilerInfo.profileFd = fd;
21508 proc.thread.profilerControl(start, profilerInfo, profileType);
21512 stopProfilerLocked(proc, profileType);
21513 if (profilerInfo != null && profilerInfo.profileFd != null) {
21515 profilerInfo.profileFd.close();
21516 } catch (IOException e) {
21523 } catch (RemoteException e) {
21524 throw new IllegalStateException("Process disappeared");
21526 if (profilerInfo != null && profilerInfo.profileFd != null) {
21528 profilerInfo.profileFd.close();
21529 } catch (IOException e) {
21535 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21536 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21537 userId, true, ALLOW_FULL_ONLY, callName, null);
21538 ProcessRecord proc = null;
21540 int pid = Integer.parseInt(process);
21541 synchronized (mPidsSelfLocked) {
21542 proc = mPidsSelfLocked.get(pid);
21544 } catch (NumberFormatException e) {
21547 if (proc == null) {
21548 ArrayMap<String, SparseArray<ProcessRecord>> all
21549 = mProcessNames.getMap();
21550 SparseArray<ProcessRecord> procs = all.get(process);
21551 if (procs != null && procs.size() > 0) {
21552 proc = procs.valueAt(0);
21553 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21554 for (int i=1; i<procs.size(); i++) {
21555 ProcessRecord thisProc = procs.valueAt(i);
21556 if (thisProc.userId == userId) {
21568 public boolean dumpHeap(String process, int userId, boolean managed,
21569 String path, ParcelFileDescriptor fd) throws RemoteException {
21572 synchronized (this) {
21573 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21574 // its own permission (same as profileControl).
21575 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21576 != PackageManager.PERMISSION_GRANTED) {
21577 throw new SecurityException("Requires permission "
21578 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21582 throw new IllegalArgumentException("null fd");
21585 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21586 if (proc == null || proc.thread == null) {
21587 throw new IllegalArgumentException("Unknown process: " + process);
21590 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21591 if (!isDebuggable) {
21592 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21593 throw new SecurityException("Process not debuggable: " + proc);
21597 proc.thread.dumpHeap(managed, path, fd);
21601 } catch (RemoteException e) {
21602 throw new IllegalStateException("Process disappeared");
21607 } catch (IOException e) {
21614 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21615 String reportPackage) {
21616 if (processName != null) {
21617 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21618 "setDumpHeapDebugLimit()");
21620 synchronized (mPidsSelfLocked) {
21621 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21622 if (proc == null) {
21623 throw new SecurityException("No process found for calling pid "
21624 + Binder.getCallingPid());
21626 if (!Build.IS_DEBUGGABLE
21627 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21628 throw new SecurityException("Not running a debuggable build");
21630 processName = proc.processName;
21632 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21633 throw new SecurityException("Package " + reportPackage + " is not running in "
21638 synchronized (this) {
21639 if (maxMemSize > 0) {
21640 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21643 mMemWatchProcesses.remove(processName, uid);
21645 mMemWatchProcesses.getMap().remove(processName);
21652 public void dumpHeapFinished(String path) {
21653 synchronized (this) {
21654 if (Binder.getCallingPid() != mMemWatchDumpPid) {
21655 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21656 + " does not match last pid " + mMemWatchDumpPid);
21659 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21660 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21661 + " does not match last path " + mMemWatchDumpFile);
21664 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21665 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21669 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21670 public void monitor() {
21671 synchronized (this) { }
21674 void onCoreSettingsChange(Bundle settings) {
21675 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21676 ProcessRecord processRecord = mLruProcesses.get(i);
21678 if (processRecord.thread != null) {
21679 processRecord.thread.setCoreSettings(settings);
21681 } catch (RemoteException re) {
21687 // Multi-user methods
21690 * Start user, if its not already running, but don't bring it to foreground.
21693 public boolean startUserInBackground(final int userId) {
21694 return mUserController.startUser(userId, /* foreground */ false);
21698 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21699 return mUserController.unlockUser(userId, token, secret, listener);
21703 public boolean switchUser(final int targetUserId) {
21704 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21705 UserInfo currentUserInfo;
21706 UserInfo targetUserInfo;
21707 synchronized (this) {
21708 int currentUserId = mUserController.getCurrentUserIdLocked();
21709 currentUserInfo = mUserController.getUserInfo(currentUserId);
21710 targetUserInfo = mUserController.getUserInfo(targetUserId);
21711 if (targetUserInfo == null) {
21712 Slog.w(TAG, "No user info for user #" + targetUserId);
21715 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21716 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21717 + " when device is in demo mode");
21720 if (!targetUserInfo.supportsSwitchTo()) {
21721 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21724 if (targetUserInfo.isManagedProfile()) {
21725 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21728 mUserController.setTargetUserIdLocked(targetUserId);
21730 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21731 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21732 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21736 void scheduleStartProfilesLocked() {
21737 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21738 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21739 DateUtils.SECOND_IN_MILLIS);
21744 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21745 return mUserController.stopUser(userId, force, callback);
21749 public UserInfo getCurrentUser() {
21750 return mUserController.getCurrentUser();
21754 public boolean isUserRunning(int userId, int flags) {
21755 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21756 && checkCallingPermission(INTERACT_ACROSS_USERS)
21757 != PackageManager.PERMISSION_GRANTED) {
21758 String msg = "Permission Denial: isUserRunning() from pid="
21759 + Binder.getCallingPid()
21760 + ", uid=" + Binder.getCallingUid()
21761 + " requires " + INTERACT_ACROSS_USERS;
21763 throw new SecurityException(msg);
21765 synchronized (this) {
21766 return mUserController.isUserRunningLocked(userId, flags);
21771 public int[] getRunningUserIds() {
21772 if (checkCallingPermission(INTERACT_ACROSS_USERS)
21773 != PackageManager.PERMISSION_GRANTED) {
21774 String msg = "Permission Denial: isUserRunning() from pid="
21775 + Binder.getCallingPid()
21776 + ", uid=" + Binder.getCallingUid()
21777 + " requires " + INTERACT_ACROSS_USERS;
21779 throw new SecurityException(msg);
21781 synchronized (this) {
21782 return mUserController.getStartedUserArrayLocked();
21787 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21788 mUserController.registerUserSwitchObserver(observer, name);
21792 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21793 mUserController.unregisterUserSwitchObserver(observer);
21796 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21797 if (info == null) return null;
21798 ApplicationInfo newInfo = new ApplicationInfo(info);
21799 newInfo.initForUser(userId);
21803 public boolean isUserStopped(int userId) {
21804 synchronized (this) {
21805 return mUserController.getStartedUserStateLocked(userId) == null;
21809 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21811 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21815 ActivityInfo info = new ActivityInfo(aInfo);
21816 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21820 private boolean processSanityChecksLocked(ProcessRecord process) {
21821 if (process == null || process.thread == null) {
21825 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21826 if (!isDebuggable) {
21827 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21835 public boolean startBinderTracking() throws RemoteException {
21836 synchronized (this) {
21837 mBinderTransactionTrackingEnabled = true;
21838 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21839 // permission (same as profileControl).
21840 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21841 != PackageManager.PERMISSION_GRANTED) {
21842 throw new SecurityException("Requires permission "
21843 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21846 for (int i = 0; i < mLruProcesses.size(); i++) {
21847 ProcessRecord process = mLruProcesses.get(i);
21848 if (!processSanityChecksLocked(process)) {
21852 process.thread.startBinderTracking();
21853 } catch (RemoteException e) {
21854 Log.v(TAG, "Process disappared");
21861 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21863 synchronized (this) {
21864 mBinderTransactionTrackingEnabled = false;
21865 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21866 // permission (same as profileControl).
21867 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21868 != PackageManager.PERMISSION_GRANTED) {
21869 throw new SecurityException("Requires permission "
21870 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21874 throw new IllegalArgumentException("null fd");
21877 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21878 pw.println("Binder transaction traces for all processes.\n");
21879 for (ProcessRecord process : mLruProcesses) {
21880 if (!processSanityChecksLocked(process)) {
21884 pw.println("Traces for process: " + process.processName);
21887 TransferPipe tp = new TransferPipe();
21889 process.thread.stopBinderTrackingAndDump(
21890 tp.getWriteFd().getFileDescriptor());
21891 tp.go(fd.getFileDescriptor());
21895 } catch (IOException e) {
21896 pw.println("Failure while dumping IPC traces from " + process +
21897 ". Exception: " + e);
21899 } catch (RemoteException e) {
21900 pw.println("Got a RemoteException while dumping IPC traces from " +
21901 process + ". Exception: " + e);
21912 } catch (IOException e) {
21918 private final class LocalService extends ActivityManagerInternal {
21920 public String checkContentProviderAccess(String authority, int userId) {
21921 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21925 public void onWakefulnessChanged(int wakefulness) {
21926 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21930 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21931 String processName, String abiOverride, int uid, Runnable crashHandler) {
21932 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21933 processName, abiOverride, uid, crashHandler);
21937 public SleepToken acquireSleepToken(String tag) {
21938 Preconditions.checkNotNull(tag);
21940 ComponentName requestedVrService = null;
21941 ComponentName callingVrActivity = null;
21943 synchronized (ActivityManagerService.this) {
21944 if (mFocusedActivity != null) {
21945 requestedVrService = mFocusedActivity.requestedVrComponent;
21946 callingVrActivity = mFocusedActivity.info.getComponentName();
21947 userId = mFocusedActivity.userId;
21951 if (requestedVrService != null) {
21952 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21955 synchronized (ActivityManagerService.this) {
21956 SleepTokenImpl token = new SleepTokenImpl(tag);
21957 mSleepTokens.add(token);
21958 updateSleepIfNeededLocked();
21964 public ComponentName getHomeActivityForUser(int userId) {
21965 synchronized (ActivityManagerService.this) {
21966 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21967 return homeActivity == null ? null : homeActivity.realActivity;
21972 public void onUserRemoved(int userId) {
21973 synchronized (ActivityManagerService.this) {
21974 ActivityManagerService.this.onUserStoppedLocked(userId);
21979 public void onLocalVoiceInteractionStarted(IBinder activity,
21980 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21981 synchronized (ActivityManagerService.this) {
21982 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21983 voiceSession, voiceInteractor);
21988 public void notifyStartingWindowDrawn() {
21989 synchronized (ActivityManagerService.this) {
21990 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21995 public void notifyAppTransitionStarting(int reason) {
21996 synchronized (ActivityManagerService.this) {
21997 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22002 public void notifyAppTransitionFinished() {
22003 synchronized (ActivityManagerService.this) {
22004 mStackSupervisor.notifyAppTransitionDone();
22009 public void notifyAppTransitionCancelled() {
22010 synchronized (ActivityManagerService.this) {
22011 mStackSupervisor.notifyAppTransitionDone();
22016 public List<IBinder> getTopVisibleActivities() {
22017 synchronized (ActivityManagerService.this) {
22018 return mStackSupervisor.getTopVisibleActivities();
22023 public void notifyDockedStackMinimizedChanged(boolean minimized) {
22024 synchronized (ActivityManagerService.this) {
22025 mStackSupervisor.setDockedStackMinimized(minimized);
22030 public void killForegroundAppsForUser(int userHandle) {
22031 synchronized (ActivityManagerService.this) {
22032 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22033 final int NP = mProcessNames.getMap().size();
22034 for (int ip = 0; ip < NP; ip++) {
22035 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22036 final int NA = apps.size();
22037 for (int ia = 0; ia < NA; ia++) {
22038 final ProcessRecord app = apps.valueAt(ia);
22039 if (app.persistent) {
22040 // We don't kill persistent processes.
22045 } else if (app.userId == userHandle && app.foregroundActivities) {
22046 app.removed = true;
22052 final int N = procs.size();
22053 for (int i = 0; i < N; i++) {
22054 removeProcessLocked(procs.get(i), false, true, "kill all fg");
22060 public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22061 if (!(target instanceof PendingIntentRecord)) {
22062 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22065 ((PendingIntentRecord) target).setWhitelistDuration(duration);
22069 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22071 Preconditions.checkNotNull(values, "Configuration must not be null");
22072 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22073 synchronized (ActivityManagerService.this) {
22074 updateConfigurationLocked(values, null, false, true, userId,
22075 false /* deferResume */);
22080 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22082 Preconditions.checkNotNull(intents, "intents");
22083 final String[] resolvedTypes = new String[intents.length];
22084 for (int i = 0; i < intents.length; i++) {
22085 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22088 // UID of the package on user userId.
22089 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22090 // packageUid may not be initialized.
22091 int packageUid = 0;
22093 packageUid = AppGlobals.getPackageManager().getPackageUid(
22094 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22095 } catch (RemoteException e) {
22096 // Shouldn't happen.
22099 synchronized (ActivityManagerService.this) {
22100 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22101 /*resultTo*/ null, bOptions, userId);
22106 public int getUidProcessState(int uid) {
22107 return getUidState(uid);
22111 private final class SleepTokenImpl extends SleepToken {
22112 private final String mTag;
22113 private final long mAcquireTime;
22115 public SleepTokenImpl(String tag) {
22117 mAcquireTime = SystemClock.uptimeMillis();
22121 public void release() {
22122 synchronized (ActivityManagerService.this) {
22123 if (mSleepTokens.remove(this)) {
22124 updateSleepIfNeededLocked();
22130 public String toString() {
22131 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22136 * An implementation of IAppTask, that allows an app to manage its own tasks via
22137 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
22138 * only the process that calls getAppTasks() can call the AppTask methods.
22140 class AppTaskImpl extends IAppTask.Stub {
22141 private int mTaskId;
22142 private int mCallingUid;
22144 public AppTaskImpl(int taskId, int callingUid) {
22146 mCallingUid = callingUid;
22149 private void checkCaller() {
22150 if (mCallingUid != Binder.getCallingUid()) {
22151 throw new SecurityException("Caller " + mCallingUid
22152 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22157 public void finishAndRemoveTask() {
22160 synchronized (ActivityManagerService.this) {
22161 long origId = Binder.clearCallingIdentity();
22163 // We remove the task from recents to preserve backwards
22164 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22165 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22168 Binder.restoreCallingIdentity(origId);
22174 public ActivityManager.RecentTaskInfo getTaskInfo() {
22177 synchronized (ActivityManagerService.this) {
22178 long origId = Binder.clearCallingIdentity();
22180 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22182 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22184 return createRecentTaskInfoFromTaskRecord(tr);
22186 Binder.restoreCallingIdentity(origId);
22192 public void moveToFront() {
22194 // Will bring task to front if it already has a root activity.
22195 final long origId = Binder.clearCallingIdentity();
22197 synchronized (this) {
22198 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22201 Binder.restoreCallingIdentity(origId);
22206 public int startActivity(IBinder whoThread, String callingPackage,
22207 Intent intent, String resolvedType, Bundle bOptions) {
22210 int callingUser = UserHandle.getCallingUserId();
22212 IApplicationThread appThread;
22213 synchronized (ActivityManagerService.this) {
22214 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22216 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22218 appThread = ApplicationThreadNative.asInterface(whoThread);
22219 if (appThread == null) {
22220 throw new IllegalArgumentException("Bad app thread " + appThread);
22223 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22224 resolvedType, null, null, null, null, 0, 0, null, null,
22225 null, bOptions, false, callingUser, null, tr);
22229 public void setExcludeFromRecents(boolean exclude) {
22232 synchronized (ActivityManagerService.this) {
22233 long origId = Binder.clearCallingIdentity();
22235 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22237 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22239 Intent intent = tr.getBaseIntent();
22241 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22243 intent.setFlags(intent.getFlags()
22244 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22247 Binder.restoreCallingIdentity(origId);
22254 * Kill processes for the user with id userId and that depend on the package named packageName
22257 public void killPackageDependents(String packageName, int userId) {
22258 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22259 if (packageName == null) {
22260 throw new NullPointerException(
22261 "Cannot kill the dependents of a package without its name.");
22264 long callingId = Binder.clearCallingIdentity();
22265 IPackageManager pm = AppGlobals.getPackageManager();
22268 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22269 } catch (RemoteException e) {
22271 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22272 throw new IllegalArgumentException(
22273 "Cannot kill dependents of non-existing package " + packageName);
22276 synchronized(this) {
22277 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22278 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22279 "dep: " + packageName);
22282 Binder.restoreCallingIdentity(callingId);
22287 public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22288 final int userId = intent.getCreatorUserHandle().getIdentifier();
22289 if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22292 IIntentSender target = intent.getTarget();
22293 if (!(target instanceof PendingIntentRecord)) {
22296 final PendingIntentRecord record = (PendingIntentRecord) target;
22297 final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22298 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22299 // For direct boot aware activities, they can be shown without triggering a work challenge
22300 // before the profile user is unlocked.
22301 return rInfo != null && rInfo.activityInfo != null;