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.annotation.UserIdInt;
67 import android.app.Activity;
68 import android.app.ActivityManager;
69 import android.app.ActivityManager.RunningTaskInfo;
70 import android.app.ActivityManager.StackId;
71 import android.app.ActivityManager.StackInfo;
72 import android.app.ActivityManager.TaskThumbnailInfo;
73 import android.app.ActivityManagerInternal;
74 import android.app.ActivityManagerInternal.SleepToken;
75 import android.app.ActivityManagerNative;
76 import android.app.ActivityOptions;
77 import android.app.ActivityThread;
78 import android.app.AlertDialog;
79 import android.app.AppGlobals;
80 import android.app.AppOpsManager;
81 import android.app.ApplicationErrorReport;
82 import android.app.ApplicationThreadNative;
83 import android.app.BroadcastOptions;
84 import android.app.Dialog;
85 import android.app.IActivityContainer;
86 import android.app.IActivityContainerCallback;
87 import android.app.IActivityController;
88 import android.app.IAppTask;
89 import android.app.IApplicationThread;
90 import android.app.IInstrumentationWatcher;
91 import android.app.INotificationManager;
92 import android.app.IProcessObserver;
93 import android.app.IServiceConnection;
94 import android.app.IStopUserCallback;
95 import android.app.ITaskStackListener;
96 import android.app.IUiAutomationConnection;
97 import android.app.IUidObserver;
98 import android.app.IUserSwitchObserver;
99 import android.app.Instrumentation;
100 import android.app.Notification;
101 import android.app.NotificationManager;
102 import android.app.PendingIntent;
103 import android.app.ProfilerInfo;
104 import android.app.admin.DevicePolicyManager;
105 import android.app.assist.AssistContent;
106 import android.app.assist.AssistStructure;
107 import android.app.backup.IBackupManager;
108 import android.app.usage.UsageEvents;
109 import android.app.usage.UsageStatsManagerInternal;
110 import android.appwidget.AppWidgetManager;
111 import android.content.ActivityNotFoundException;
112 import android.content.BroadcastReceiver;
113 import android.content.ClipData;
114 import android.content.ComponentCallbacks2;
115 import android.content.ComponentName;
116 import android.content.ContentProvider;
117 import android.content.ContentResolver;
118 import android.content.Context;
119 import android.content.DialogInterface;
120 import android.content.IContentProvider;
121 import android.content.IIntentReceiver;
122 import android.content.IIntentSender;
123 import android.content.Intent;
124 import android.content.IntentFilter;
125 import android.content.IntentSender;
126 import android.content.pm.ActivityInfo;
127 import android.content.pm.ApplicationInfo;
128 import android.content.pm.ConfigurationInfo;
129 import android.content.pm.IPackageDataObserver;
130 import android.content.pm.IPackageManager;
131 import android.content.pm.InstrumentationInfo;
132 import android.content.pm.PackageInfo;
133 import android.content.pm.PackageManager;
134 import android.content.pm.PackageManager.NameNotFoundException;
135 import android.content.pm.PackageManagerInternal;
136 import android.content.pm.ParceledListSlice;
137 import android.content.pm.PathPermission;
138 import android.content.pm.PermissionInfo;
139 import android.content.pm.ProviderInfo;
140 import android.content.pm.ResolveInfo;
141 import android.content.pm.ServiceInfo;
142 import android.content.pm.ShortcutServiceInternal;
143 import android.content.pm.UserInfo;
144 import android.content.res.CompatibilityInfo;
145 import android.content.res.Configuration;
146 import android.content.res.Resources;
147 import android.database.ContentObserver;
148 import android.graphics.Bitmap;
149 import android.graphics.Point;
150 import android.graphics.Rect;
151 import android.location.LocationManager;
152 import android.net.Proxy;
153 import android.net.ProxyInfo;
154 import android.net.Uri;
155 import android.os.BatteryStats;
156 import android.os.Binder;
157 import android.os.Build;
158 import android.os.Bundle;
159 import android.os.Debug;
160 import android.os.DropBoxManager;
161 import android.os.Environment;
162 import android.os.FactoryTest;
163 import android.os.FileObserver;
164 import android.os.FileUtils;
165 import android.os.Handler;
166 import android.os.IBinder;
167 import android.os.IPermissionController;
168 import android.os.IProcessInfoService;
169 import android.os.IProgressListener;
170 import android.os.LocaleList;
171 import android.os.Looper;
172 import android.os.Message;
173 import android.os.Parcel;
174 import android.os.ParcelFileDescriptor;
175 import android.os.PersistableBundle;
176 import android.os.PowerManager;
177 import android.os.PowerManagerInternal;
178 import android.os.Process;
179 import android.os.RemoteCallbackList;
180 import android.os.RemoteException;
181 import android.os.ResultReceiver;
182 import android.os.ServiceManager;
183 import android.os.StrictMode;
184 import android.os.SystemClock;
185 import android.os.SystemProperties;
186 import android.os.Trace;
187 import android.os.TransactionTooLargeException;
188 import android.os.UpdateLock;
189 import android.os.UserHandle;
190 import android.os.UserManager;
191 import android.os.WorkSource;
192 import android.provider.Downloads;
193 import android.os.storage.IMountService;
194 import android.os.storage.MountServiceInternal;
195 import android.os.storage.StorageManager;
196 import android.provider.Settings;
197 import android.service.voice.IVoiceInteractionSession;
198 import android.service.voice.VoiceInteractionManagerInternal;
199 import android.service.voice.VoiceInteractionSession;
200 import android.telecom.TelecomManager;
201 import android.text.format.DateUtils;
202 import android.text.format.Time;
203 import android.text.style.SuggestionSpan;
204 import android.util.ArrayMap;
205 import android.util.ArraySet;
206 import android.util.AtomicFile;
207 import android.util.DebugUtils;
208 import android.util.DisplayMetrics;
209 import android.util.EventLog;
210 import android.util.Log;
211 import android.util.Pair;
212 import android.util.PrintWriterPrinter;
213 import android.util.Slog;
214 import android.util.SparseArray;
215 import android.util.TimeUtils;
216 import android.util.Xml;
217 import android.view.Display;
218 import android.view.Gravity;
219 import android.view.LayoutInflater;
220 import android.view.View;
221 import android.view.WindowManager;
224 import java.io.FileDescriptor;
225 import java.io.FileInputStream;
226 import java.io.FileNotFoundException;
227 import java.io.FileOutputStream;
228 import java.io.IOException;
229 import java.io.InputStreamReader;
230 import java.io.PrintWriter;
231 import java.io.StringWriter;
232 import java.lang.ref.WeakReference;
233 import java.nio.charset.StandardCharsets;
234 import java.util.ArrayList;
235 import java.util.Arrays;
236 import java.util.Collections;
237 import java.util.Comparator;
238 import java.util.HashMap;
239 import java.util.HashSet;
240 import java.util.Iterator;
241 import java.util.List;
242 import java.util.Locale;
243 import java.util.Map;
244 import java.util.Objects;
245 import java.util.Set;
246 import java.util.concurrent.atomic.AtomicBoolean;
247 import java.util.concurrent.atomic.AtomicLong;
249 import dalvik.system.VMRuntime;
251 import libcore.io.IoUtils;
252 import libcore.util.EmptyArray;
254 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
268 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269 import static android.content.pm.PackageManager.GET_PROVIDERS;
270 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277 import static android.os.Process.PROC_CHAR;
278 import static android.os.Process.PROC_OUT_LONG;
279 import static android.os.Process.PROC_PARENS;
280 import static android.os.Process.PROC_SPACE_TERM;
281 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
282 import static android.provider.Settings.Global.DEBUG_APP;
283 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
284 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
286 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
287 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
288 import static android.provider.Settings.System.FONT_SCALE;
289 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
290 import static com.android.internal.util.XmlUtils.readIntAttribute;
291 import static com.android.internal.util.XmlUtils.readLongAttribute;
292 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
293 import static com.android.internal.util.XmlUtils.writeIntAttribute;
294 import static com.android.internal.util.XmlUtils.writeLongAttribute;
295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
352 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
354 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
355 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
356 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
357 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
358 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
359 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
360 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
361 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
362 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
365 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
367 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
370 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
371 import static org.xmlpull.v1.XmlPullParser.START_TAG;
373 public final class ActivityManagerService extends ActivityManagerNative
374 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
376 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
377 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
378 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
379 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
380 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
381 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
382 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
383 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
384 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
385 private static final String TAG_LRU = TAG + POSTFIX_LRU;
386 private static final String TAG_MU = TAG + POSTFIX_MU;
387 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
388 private static final String TAG_POWER = TAG + POSTFIX_POWER;
389 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
390 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
391 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
392 private static final String TAG_PSS = TAG + POSTFIX_PSS;
393 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
394 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
395 private static final String TAG_STACK = TAG + POSTFIX_STACK;
396 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
397 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
398 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
399 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
400 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
402 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
403 // here so that while the job scheduler can depend on AMS, the other way around
404 // need not be the case.
405 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
407 /** Control over CPU and battery monitoring */
408 // write battery stats every 30 minutes.
409 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
410 static final boolean MONITOR_CPU_USAGE = true;
411 // don't sample cpu less than every 5 seconds.
412 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
413 // wait possibly forever for next cpu sample.
414 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
415 static final boolean MONITOR_THREAD_CPU_USAGE = false;
417 // The flags that are set for all calls we make to the package manager.
418 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
420 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
422 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
424 // Amount of time after a call to stopAppSwitches() during which we will
425 // prevent further untrusted switches from happening.
426 static final long APP_SWITCH_DELAY_TIME = 5*1000;
428 // How long we wait for a launched process to attach to the activity manager
429 // before we decide it's never going to come up for real.
430 static final int PROC_START_TIMEOUT = 10*1000;
431 // How long we wait for an attached process to publish its content providers
432 // before we decide it must be hung.
433 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
435 // How long we will retain processes hosting content providers in the "last activity"
436 // state before allowing them to drop down to the regular cached LRU list. This is
437 // to avoid thrashing of provider processes under low memory situations.
438 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
440 // How long we wait for a launched process to attach to the activity manager
441 // before we decide it's never going to come up for real, when the process was
442 // started with a wrapper for instrumentation (such as Valgrind) because it
443 // could take much longer than usual.
444 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
446 // How long to wait after going idle before forcing apps to GC.
447 static final int GC_TIMEOUT = 5*1000;
449 // The minimum amount of time between successive GC requests for a process.
450 static final int GC_MIN_INTERVAL = 60*1000;
452 // The minimum amount of time between successive PSS requests for a process.
453 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
455 // The minimum amount of time between successive PSS requests for a process
456 // when the request is due to the memory state being lowered.
457 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
459 // The rate at which we check for apps using excessive power -- 15 mins.
460 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
462 // The minimum sample duration we will allow before deciding we have
463 // enough data on wake locks to start killing things.
464 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
466 // The minimum sample duration we will allow before deciding we have
467 // enough data on CPU usage to start killing things.
468 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
470 // How long we allow a receiver to run before giving up on it.
471 static final int BROADCAST_FG_TIMEOUT = 10*1000;
472 static final int BROADCAST_BG_TIMEOUT = 60*1000;
474 // How long we wait until we timeout on key dispatching.
475 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
477 // How long we wait until we timeout on key dispatching during instrumentation.
478 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
480 // This is the amount of time an app needs to be running a foreground service before
481 // we will consider it to be doing interaction for usage stats.
482 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
484 // Maximum amount of time we will allow to elapse before re-reporting usage stats
485 // interaction with foreground processes.
486 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
488 // This is the amount of time we allow an app to settle after it goes into the background,
489 // before we start restricting what it can do.
490 static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
492 // How long to wait in getAssistContextExtras for the activity and foreground services
493 // to respond with the result.
494 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
496 // How long top wait when going through the modern assist (which doesn't need to block
497 // on getting this result before starting to launch its UI).
498 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
500 // Maximum number of persisted Uri grants a package is allowed
501 static final int MAX_PERSISTED_URI_GRANTS = 128;
503 static final int MY_PID = Process.myPid();
505 static final String[] EMPTY_STRING_ARRAY = new String[0];
507 // How many bytes to write into the dropbox log before truncating
508 static final int DROPBOX_MAX_SIZE = 192 * 1024;
509 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
510 // as one line, but close enough for now.
511 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
513 // Access modes for handleIncomingUser.
514 static final int ALLOW_NON_FULL = 0;
515 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
516 static final int ALLOW_FULL_ONLY = 2;
518 // Delay in notifying task stack change listeners (in millis)
519 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
521 // Necessary ApplicationInfo flags to mark an app as persistent
522 private static final int PERSISTENT_MASK =
523 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
525 // Intent sent when remote bugreport collection has been completed
526 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
527 "android.intent.action.REMOTE_BUGREPORT_FINISHED";
529 // Delay to disable app launch boost
530 static final int APP_BOOST_MESSAGE_DELAY = 3000;
531 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
532 static final int APP_BOOST_TIMEOUT = 2500;
534 // Used to indicate that a task is removed it should also be removed from recents.
535 private static final boolean REMOVE_FROM_RECENTS = true;
536 // Used to indicate that an app transition should be animated.
537 static final boolean ANIMATE = true;
539 // Determines whether to take full screen screenshots
540 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
541 public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
543 private static native int nativeMigrateToBoost();
544 private static native int nativeMigrateFromBoost();
545 private boolean mIsBoosted = false;
546 private long mBoostStartTime = 0;
548 /** All system services */
549 SystemServiceManager mSystemServiceManager;
551 private Installer mInstaller;
553 /** Run all ActivityStacks through this */
554 final ActivityStackSupervisor mStackSupervisor;
556 final ActivityStarter mActivityStarter;
558 /** Task stack change listeners. */
559 private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
560 new RemoteCallbackList<ITaskStackListener>();
562 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
564 public IntentFirewall mIntentFirewall;
566 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
567 // default actuion automatically. Important for devices without direct input
569 private boolean mShowDialogs = true;
570 private boolean mInVrMode = false;
572 BroadcastQueue mFgBroadcastQueue;
573 BroadcastQueue mBgBroadcastQueue;
574 // Convenient for easy iteration over the queues. Foreground is first
575 // so that dispatch of foreground broadcasts gets precedence.
576 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
578 BroadcastStats mLastBroadcastStats;
579 BroadcastStats mCurBroadcastStats;
581 BroadcastQueue broadcastQueueForIntent(Intent intent) {
582 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
583 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
584 "Broadcast intent " + intent + " on "
585 + (isFg ? "foreground" : "background") + " queue");
586 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
590 * Activity we have told the window manager to have key focus.
592 ActivityRecord mFocusedActivity = null;
595 * User id of the last activity mFocusedActivity was set to.
597 private int mLastFocusedUserId;
600 * If non-null, we are tracking the time the user spends in the currently focused app.
602 private AppTimeTracker mCurAppTimeTracker;
605 * List of intents that were used to start the most recent tasks.
607 final RecentTasks mRecentTasks;
610 * For addAppTask: cached of the last activity component that was added.
612 ComponentName mLastAddedTaskComponent;
615 * For addAppTask: cached of the last activity uid that was added.
617 int mLastAddedTaskUid;
620 * For addAppTask: cached of the last ActivityInfo that was added.
622 ActivityInfo mLastAddedTaskActivity;
625 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
627 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
630 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
632 String mDeviceOwnerName;
634 final UserController mUserController;
636 final AppErrors mAppErrors;
638 boolean mDoingSetFocusedActivity;
640 public boolean canShowErrorDialogs() {
641 return mShowDialogs && !mSleeping && !mShuttingDown;
644 // it's a semaphore; boost when 0->1, reset when 1->0
645 static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
646 @Override protected Integer initialValue() {
651 static void boostPriorityForLockedSection() {
652 if (sIsBoosted.get() == 0) {
653 // boost to prio 118 while holding a global lock
654 Process.setThreadPriority(Process.myTid(), -2);
655 //Log.e(TAG, "PRIORITY BOOST: set priority on TID " + Process.myTid());
657 int cur = sIsBoosted.get();
658 sIsBoosted.set(cur + 1);
661 static void resetPriorityAfterLockedSection() {
662 sIsBoosted.set(sIsBoosted.get() - 1);
663 if (sIsBoosted.get() == 0) {
664 //Log.e(TAG, "PRIORITY BOOST: reset priority on TID " + Process.myTid());
665 Process.setThreadPriority(Process.myTid(), 0);
668 public class PendingAssistExtras extends Binder implements Runnable {
669 public final ActivityRecord activity;
670 public final Bundle extras;
671 public final Intent intent;
672 public final String hint;
673 public final IResultReceiver receiver;
674 public final int userHandle;
675 public boolean haveResult = false;
676 public Bundle result = null;
677 public AssistStructure structure = null;
678 public AssistContent content = null;
679 public Bundle receiverExtras;
681 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
682 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
683 activity = _activity;
687 receiver = _receiver;
688 receiverExtras = _receiverExtras;
689 userHandle = _userHandle;
693 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
694 synchronized (this) {
698 pendingAssistExtrasTimedOut(this);
702 final ArrayList<PendingAssistExtras> mPendingAssistExtras
703 = new ArrayList<PendingAssistExtras>();
706 * Process management.
708 final ProcessList mProcessList = new ProcessList();
711 * All of the applications we currently have running organized by name.
712 * The keys are strings of the application package name (as
713 * returned by the package manager), and the keys are ApplicationRecord
716 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
719 * Tracking long-term execution of processes to look for abuse and other
722 final ProcessStatsService mProcessStats;
725 * The currently running isolated processes.
727 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
730 * Counter for assigning isolated process uids, to avoid frequently reusing the
733 int mNextIsolatedProcessUid = 0;
736 * The currently running heavy-weight process, if any.
738 ProcessRecord mHeavyWeightProcess = null;
741 * All of the processes we currently have running organized by pid.
742 * The keys are the pid running the application.
744 * <p>NOTE: This object is protected by its own lock, NOT the global
745 * activity manager lock!
747 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
750 * All of the processes that have been forced to be foreground. The key
751 * is the pid of the caller who requested it (we hold a death
754 abstract class ForegroundToken implements IBinder.DeathRecipient {
758 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
761 * List of records for processes that someone had tried to start before the
762 * system was ready. We don't start them at that point, but ensure they
763 * are started by the time booting is complete.
765 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
768 * List of persistent applications that are in the process
771 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
774 * Processes that are being forcibly torn down.
776 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
779 * List of running applications, sorted by recent usage.
780 * The first entry in the list is the least recently used.
782 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
785 * Where in mLruProcesses that the processes hosting activities start.
787 int mLruProcessActivityStart = 0;
790 * Where in mLruProcesses that the processes hosting services start.
791 * This is after (lower index) than mLruProcessesActivityStart.
793 int mLruProcessServiceStart = 0;
796 * List of processes that should gc as soon as things are idle.
798 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
801 * Processes we want to collect PSS data from.
803 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
805 private boolean mBinderTransactionTrackingEnabled = false;
808 * Last time we requested PSS data of all processes.
810 long mLastFullPssTime = SystemClock.uptimeMillis();
813 * If set, the next time we collect PSS data we should do a full collection
814 * with data from native processes and the kernel.
816 boolean mFullPssPending = false;
819 * This is the process holding what we currently consider to be
820 * the "home" activity.
822 ProcessRecord mHomeProcess;
825 * This is the process holding the activity the user last visited that
826 * is in a different process from the one they are currently in.
828 ProcessRecord mPreviousProcess;
831 * The time at which the previous process was last visible.
833 long mPreviousProcessVisibleTime;
836 * Track all uids that have actively running processes.
838 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
841 * This is for verifying the UID report flow.
843 static final boolean VALIDATE_UID_STATES = true;
844 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
847 * Packages that the user has asked to have run in screen size
848 * compatibility mode instead of filling the screen.
850 final CompatModePackages mCompatModePackages;
853 * Set of IntentSenderRecord objects that are currently active.
855 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
856 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
859 * Fingerprints (hashCode()) of stack traces that we've
860 * already logged DropBox entries for. Guarded by itself. If
861 * something (rogue user app) forces this over
862 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
864 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
865 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
868 * Strict Mode background batched logging state.
870 * The string buffer is guarded by itself, and its lock is also
871 * used to determine if another batched write is already
874 private final StringBuilder mStrictModeBuffer = new StringBuilder();
877 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
878 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
880 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
883 * Resolver for broadcast intents to registered receivers.
884 * Holds BroadcastFilter (subclass of IntentFilter).
886 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
887 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
889 protected boolean allowFilterResult(
890 BroadcastFilter filter, List<BroadcastFilter> dest) {
891 IBinder target = filter.receiverList.receiver.asBinder();
892 for (int i = dest.size() - 1; i >= 0; i--) {
893 if (dest.get(i).receiverList.receiver.asBinder() == target) {
901 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
902 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
903 || userId == filter.owningUserId) {
904 return super.newResult(filter, match, userId);
910 protected BroadcastFilter[] newArray(int size) {
911 return new BroadcastFilter[size];
915 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
916 return packageName.equals(filter.packageName);
921 * State of all active sticky broadcasts per user. Keys are the action of the
922 * sticky Intent, values are an ArrayList of all broadcasted intents with
923 * that action (which should usually be one). The SparseArray is keyed
924 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
925 * for stickies that are sent to all users.
927 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
928 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
930 final ActiveServices mServices;
932 final static class Association {
933 final int mSourceUid;
934 final String mSourceProcess;
935 final int mTargetUid;
936 final ComponentName mTargetComponent;
937 final String mTargetProcess;
945 // states of the source process when the bind occurred.
946 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
947 long mLastStateUptime;
948 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
949 - ActivityManager.MIN_PROCESS_STATE+1];
951 Association(int sourceUid, String sourceProcess, int targetUid,
952 ComponentName targetComponent, String targetProcess) {
953 mSourceUid = sourceUid;
954 mSourceProcess = sourceProcess;
955 mTargetUid = targetUid;
956 mTargetComponent = targetComponent;
957 mTargetProcess = targetProcess;
962 * When service association tracking is enabled, this is all of the associations we
963 * have seen. Mapping is target uid -> target component -> source uid -> source process name
964 * -> association data.
966 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
967 mAssociations = new SparseArray<>();
968 boolean mTrackingAssociations;
971 * Backup/restore process management
973 String mBackupAppName = null;
974 BackupRecord mBackupTarget = null;
976 final ProviderMap mProviderMap;
979 * List of content providers who have clients waiting for them. The
980 * application is currently being launched and the provider will be
981 * removed from this list once it is published.
983 final ArrayList<ContentProviderRecord> mLaunchingProviders
984 = new ArrayList<ContentProviderRecord>();
987 * File storing persisted {@link #mGrantedUriPermissions}.
989 private final AtomicFile mGrantFile;
991 /** XML constants used in {@link #mGrantFile} */
992 private static final String TAG_URI_GRANTS = "uri-grants";
993 private static final String TAG_URI_GRANT = "uri-grant";
994 private static final String ATTR_USER_HANDLE = "userHandle";
995 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
996 private static final String ATTR_TARGET_USER_ID = "targetUserId";
997 private static final String ATTR_SOURCE_PKG = "sourcePkg";
998 private static final String ATTR_TARGET_PKG = "targetPkg";
999 private static final String ATTR_URI = "uri";
1000 private static final String ATTR_MODE_FLAGS = "modeFlags";
1001 private static final String ATTR_CREATED_TIME = "createdTime";
1002 private static final String ATTR_PREFIX = "prefix";
1005 * Global set of specific {@link Uri} permissions that have been granted.
1006 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1007 * to {@link UriPermission#uri} to {@link UriPermission}.
1010 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1011 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1013 public static class GrantUri {
1014 public final int sourceUserId;
1015 public final Uri uri;
1016 public boolean prefix;
1018 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1019 this.sourceUserId = sourceUserId;
1021 this.prefix = prefix;
1025 public int hashCode() {
1027 hashCode = 31 * hashCode + sourceUserId;
1028 hashCode = 31 * hashCode + uri.hashCode();
1029 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1034 public boolean equals(Object o) {
1035 if (o instanceof GrantUri) {
1036 GrantUri other = (GrantUri) o;
1037 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1038 && prefix == other.prefix;
1044 public String toString() {
1045 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1046 if (prefix) result += " [prefix]";
1050 public String toSafeString() {
1051 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1052 if (prefix) result += " [prefix]";
1056 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1057 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1058 ContentProvider.getUriWithoutUserId(uri), false);
1062 CoreSettingsObserver mCoreSettingsObserver;
1064 FontScaleSettingObserver mFontScaleSettingObserver;
1066 private final class FontScaleSettingObserver extends ContentObserver {
1067 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1069 public FontScaleSettingObserver() {
1071 ContentResolver resolver = mContext.getContentResolver();
1072 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1076 public void onChange(boolean selfChange, Uri uri) {
1077 if (mFontScaleUri.equals(uri)) {
1078 updateFontScaleIfNeeded();
1084 * Thread-local storage used to carry caller permissions over through
1085 * indirect content-provider access.
1087 private class Identity {
1088 public final IBinder token;
1089 public final int pid;
1090 public final int uid;
1092 Identity(IBinder _token, int _pid, int _uid) {
1099 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1102 * All information we have collected about the runtime performance of
1103 * any user id that can impact battery performance.
1105 final BatteryStatsService mBatteryStatsService;
1108 * Information about component usage
1110 UsageStatsManagerInternal mUsageStatsService;
1113 * Access to DeviceIdleController service.
1115 DeviceIdleController.LocalService mLocalDeviceIdleController;
1118 * Information about and control over application operations
1120 final AppOpsService mAppOpsService;
1123 * Current configuration information. HistoryRecord objects are given
1124 * a reference to this object to indicate which configuration they are
1125 * currently running in, so this object must be kept immutable.
1127 Configuration mConfiguration = new Configuration();
1130 * Current sequencing integer of the configuration, for skipping old
1133 int mConfigurationSeq = 0;
1135 boolean mSuppressResizeConfigChanges = false;
1138 * Hardware-reported OpenGLES version.
1140 final int GL_ES_VERSION;
1143 * List of initialization arguments to pass to all processes when binding applications to them.
1144 * For example, references to the commonly used services.
1146 HashMap<String, IBinder> mAppBindArgs;
1147 HashMap<String, IBinder> mIsolatedAppBindArgs;
1150 * Temporary to avoid allocations. Protected by main lock.
1152 final StringBuilder mStringBuilder = new StringBuilder(256);
1155 * Used to control how we initialize the service.
1157 ComponentName mTopComponent;
1158 String mTopAction = Intent.ACTION_MAIN;
1161 volatile boolean mProcessesReady = false;
1162 volatile boolean mSystemReady = false;
1163 volatile boolean mOnBattery = false;
1164 volatile int mFactoryTest;
1166 @GuardedBy("this") boolean mBooting = false;
1167 @GuardedBy("this") boolean mCallFinishBooting = false;
1168 @GuardedBy("this") boolean mBootAnimationComplete = false;
1169 @GuardedBy("this") boolean mLaunchWarningShown = false;
1170 @GuardedBy("this") boolean mCheckedForSetup = false;
1175 * The time at which we will allow normal application switches again,
1176 * after a call to {@link #stopAppSwitches()}.
1178 long mAppSwitchesAllowedTime;
1181 * This is set to true after the first switch after mAppSwitchesAllowedTime
1182 * is set; any switches after that will clear the time.
1184 boolean mDidAppSwitch;
1187 * Last time (in realtime) at which we checked for power usage.
1189 long mLastPowerCheckRealtime;
1192 * Last time (in uptime) at which we checked for power usage.
1194 long mLastPowerCheckUptime;
1197 * Set while we are wanting to sleep, to prevent any
1198 * activities from being started/resumed.
1200 private boolean mSleeping = false;
1203 * The process state used for processes that are running the top activities.
1204 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1206 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1209 * Set while we are running a voice interaction. This overrides
1210 * sleeping while it is active.
1212 private IVoiceInteractionSession mRunningVoice;
1215 * For some direct access we need to power manager.
1217 PowerManagerInternal mLocalPowerManager;
1220 * We want to hold a wake lock while running a voice interaction session, since
1221 * this may happen with the screen off and we need to keep the CPU running to
1222 * be able to continue to interact with the user.
1224 PowerManager.WakeLock mVoiceWakeLock;
1227 * State of external calls telling us if the device is awake or asleep.
1229 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1232 * A list of tokens that cause the top activity to be put to sleep.
1233 * They are used by components that may hide and block interaction with underlying
1236 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1238 static final int LOCK_SCREEN_HIDDEN = 0;
1239 static final int LOCK_SCREEN_LEAVING = 1;
1240 static final int LOCK_SCREEN_SHOWN = 2;
1242 * State of external call telling us if the lock screen is shown.
1244 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1247 * Set if we are shutting down the system, similar to sleeping.
1249 boolean mShuttingDown = false;
1252 * Current sequence id for oom_adj computation traversal.
1257 * Current sequence id for process LRU updating.
1262 * Keep track of the non-cached/empty process we last found, to help
1263 * determine how to distribute cached/empty processes next time.
1265 int mNumNonCachedProcs = 0;
1268 * Keep track of the number of cached hidden procs, to balance oom adj
1269 * distribution between those and empty procs.
1271 int mNumCachedHiddenProcs = 0;
1274 * Keep track of the number of service processes we last found, to
1275 * determine on the next iteration which should be B services.
1277 int mNumServiceProcs = 0;
1278 int mNewNumAServiceProcs = 0;
1279 int mNewNumServiceProcs = 0;
1282 * Allow the current computed overall memory level of the system to go down?
1283 * This is set to false when we are killing processes for reasons other than
1284 * memory management, so that the now smaller process list will not be taken as
1285 * an indication that memory is tighter.
1287 boolean mAllowLowerMemLevel = false;
1290 * The last computed memory level, for holding when we are in a state that
1291 * processes are going away for other reasons.
1293 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1296 * The last total number of process we have, to determine if changes actually look
1297 * like a shrinking number of process due to lower RAM.
1299 int mLastNumProcesses;
1302 * The uptime of the last time we performed idle maintenance.
1304 long mLastIdleTime = SystemClock.uptimeMillis();
1307 * Total time spent with RAM that has been added in the past since the last idle time.
1309 long mLowRamTimeSinceLastIdle = 0;
1312 * If RAM is currently low, when that horrible situation started.
1314 long mLowRamStartTime = 0;
1317 * For reporting to battery stats the current top application.
1319 private String mCurResumedPackage = null;
1320 private int mCurResumedUid = -1;
1323 * For reporting to battery stats the apps currently running foreground
1324 * service. The ProcessMap is package/uid tuples; each of these contain
1325 * an array of the currently foreground processes.
1327 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1328 = new ProcessMap<ArrayList<ProcessRecord>>();
1331 * This is set if we had to do a delayed dexopt of an app before launching
1332 * it, to increase the ANR timeouts in that case.
1337 * Set if the systemServer made a call to enterSafeMode.
1342 * If true, we are running under a test environment so will sample PSS from processes
1343 * much more rapidly to try to collect better data when the tests are rapidly
1344 * running through apps.
1346 boolean mTestPssMode = false;
1348 String mDebugApp = null;
1349 boolean mWaitForDebugger = false;
1350 boolean mDebugTransient = false;
1351 String mOrigDebugApp = null;
1352 boolean mOrigWaitForDebugger = false;
1353 boolean mAlwaysFinishActivities = false;
1354 boolean mLenientBackgroundCheck = false;
1355 boolean mForceResizableActivities;
1356 boolean mSupportsMultiWindow;
1357 boolean mSupportsFreeformWindowManagement;
1358 boolean mSupportsPictureInPicture;
1359 boolean mSupportsLeanbackOnly;
1360 Rect mDefaultPinnedStackBounds;
1361 IActivityController mController = null;
1362 boolean mControllerIsAMonkey = false;
1363 String mProfileApp = null;
1364 ProcessRecord mProfileProc = null;
1365 String mProfileFile;
1366 ParcelFileDescriptor mProfileFd;
1367 int mSamplingInterval = 0;
1368 boolean mAutoStopProfiler = false;
1369 int mProfileType = 0;
1370 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1371 String mMemWatchDumpProcName;
1372 String mMemWatchDumpFile;
1373 int mMemWatchDumpPid;
1374 int mMemWatchDumpUid;
1375 String mTrackAllocationApp = null;
1376 String mNativeDebuggingApp = null;
1378 final long[] mTmpLong = new long[2];
1380 static final class ProcessChangeItem {
1381 static final int CHANGE_ACTIVITIES = 1<<0;
1382 static final int CHANGE_PROCESS_STATE = 1<<1;
1387 boolean foregroundActivities;
1390 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1391 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1393 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1394 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1396 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1397 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1399 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1400 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1403 * Runtime CPU use collection thread. This object's lock is used to
1404 * perform synchronization with the thread (notifying it to run).
1406 final Thread mProcessCpuThread;
1409 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1410 * Must acquire this object's lock when accessing it.
1411 * NOTE: this lock will be held while doing long operations (trawling
1412 * through all processes in /proc), so it should never be acquired by
1413 * any critical paths such as when holding the main activity manager lock.
1415 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1416 MONITOR_THREAD_CPU_USAGE);
1417 final AtomicLong mLastCpuTime = new AtomicLong(0);
1418 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1420 long mLastWriteTime = 0;
1423 * Used to retain an update lock when the foreground activity is in
1426 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1429 * Set to true after the system has finished booting.
1431 boolean mBooted = false;
1433 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1434 int mProcessLimitOverride = -1;
1436 WindowManagerService mWindowManager;
1437 final ActivityThread mSystemThread;
1439 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1440 final ProcessRecord mApp;
1442 final IApplicationThread mAppThread;
1444 AppDeathRecipient(ProcessRecord app, int pid,
1445 IApplicationThread thread) {
1446 if (DEBUG_ALL) Slog.v(
1447 TAG, "New death recipient " + this
1448 + " for thread " + thread.asBinder());
1451 mAppThread = thread;
1455 public void binderDied() {
1456 if (DEBUG_ALL) Slog.v(
1457 TAG, "Death received in " + this
1458 + " for thread " + mAppThread.asBinder());
1459 synchronized(ActivityManagerService.this) {
1460 appDiedLocked(mApp, mPid, mAppThread, true);
1465 static final int SHOW_ERROR_UI_MSG = 1;
1466 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1467 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1468 static final int UPDATE_CONFIGURATION_MSG = 4;
1469 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1470 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1471 static final int SERVICE_TIMEOUT_MSG = 12;
1472 static final int UPDATE_TIME_ZONE = 13;
1473 static final int SHOW_UID_ERROR_UI_MSG = 14;
1474 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1475 static final int PROC_START_TIMEOUT_MSG = 20;
1476 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1477 static final int KILL_APPLICATION_MSG = 22;
1478 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1479 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1480 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1481 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1482 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1483 static final int CLEAR_DNS_CACHE_MSG = 28;
1484 static final int UPDATE_HTTP_PROXY_MSG = 29;
1485 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1486 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1487 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1488 static final int REPORT_MEM_USAGE_MSG = 33;
1489 static final int REPORT_USER_SWITCH_MSG = 34;
1490 static final int CONTINUE_USER_SWITCH_MSG = 35;
1491 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1492 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1493 static final int PERSIST_URI_GRANTS_MSG = 38;
1494 static final int REQUEST_ALL_PSS_MSG = 39;
1495 static final int START_PROFILES_MSG = 40;
1496 static final int UPDATE_TIME = 41;
1497 static final int SYSTEM_USER_START_MSG = 42;
1498 static final int SYSTEM_USER_CURRENT_MSG = 43;
1499 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1500 static final int FINISH_BOOTING_MSG = 45;
1501 static final int START_USER_SWITCH_UI_MSG = 46;
1502 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1503 static final int DISMISS_DIALOG_UI_MSG = 48;
1504 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1505 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1506 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1507 static final int DELETE_DUMPHEAP_MSG = 52;
1508 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1509 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1510 static final int REPORT_TIME_TRACKER_MSG = 55;
1511 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1512 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1513 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1514 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1515 static final int IDLE_UIDS_MSG = 60;
1516 static final int SYSTEM_USER_UNLOCK_MSG = 61;
1517 static final int LOG_STACK_STATE = 62;
1518 static final int VR_MODE_CHANGE_MSG = 63;
1519 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1520 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1521 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1522 static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1523 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1524 static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1525 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1527 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1528 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1529 static final int FIRST_COMPAT_MODE_MSG = 300;
1530 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1532 static ServiceThread sKillThread = null;
1533 static KillHandler sKillHandler = null;
1535 CompatModeDialog mCompatModeDialog;
1536 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1537 long mLastMemUsageReportTime = 0;
1540 * Flag whether the current user is a "monkey", i.e. whether
1541 * the UI is driven by a UI automation tool.
1543 private boolean mUserIsMonkey;
1545 /** Flag whether the device has a Recents UI */
1546 boolean mHasRecents;
1548 /** The dimensions of the thumbnails in the Recents UI. */
1549 int mThumbnailWidth;
1550 int mThumbnailHeight;
1551 float mFullscreenThumbnailScale;
1553 final ServiceThread mHandlerThread;
1554 final MainHandler mHandler;
1555 final UiHandler mUiHandler;
1557 PackageManagerInternal mPackageManagerInt;
1559 // VoiceInteraction session ID that changes for each new request except when
1560 // being called for multiwindow assist in a single session.
1561 private int mViSessionId = 1000;
1563 final class KillHandler extends Handler {
1564 static final int KILL_PROCESS_GROUP_MSG = 4000;
1566 public KillHandler(Looper looper) {
1567 super(looper, null, true);
1571 public void handleMessage(Message msg) {
1573 case KILL_PROCESS_GROUP_MSG:
1575 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1576 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1577 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1582 super.handleMessage(msg);
1587 final class UiHandler extends Handler {
1588 public UiHandler() {
1589 super(com.android.server.UiThread.get().getLooper(), null, true);
1593 public void handleMessage(Message msg) {
1595 case SHOW_ERROR_UI_MSG: {
1596 mAppErrors.handleShowAppErrorUi(msg);
1597 ensureBootCompleted();
1599 case SHOW_NOT_RESPONDING_UI_MSG: {
1600 mAppErrors.handleShowAnrUi(msg);
1601 ensureBootCompleted();
1603 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1604 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1605 synchronized (ActivityManagerService.this) {
1606 ProcessRecord proc = (ProcessRecord) data.get("app");
1608 Slog.e(TAG, "App not found when showing strict mode dialog.");
1611 if (proc.crashDialog != null) {
1612 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1615 AppErrorResult res = (AppErrorResult) data.get("result");
1616 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1617 Dialog d = new StrictModeViolationDialog(mContext,
1618 ActivityManagerService.this, res, proc);
1620 proc.crashDialog = d;
1622 // The device is asleep, so just pretend that the user
1623 // saw a crash dialog and hit "force quit".
1627 ensureBootCompleted();
1629 case SHOW_FACTORY_ERROR_UI_MSG: {
1630 Dialog d = new FactoryErrorDialog(
1631 mContext, msg.getData().getCharSequence("msg"));
1633 ensureBootCompleted();
1635 case WAIT_FOR_DEBUGGER_UI_MSG: {
1636 synchronized (ActivityManagerService.this) {
1637 ProcessRecord app = (ProcessRecord)msg.obj;
1638 if (msg.arg1 != 0) {
1639 if (!app.waitedForDebugger) {
1640 Dialog d = new AppWaitingForDebuggerDialog(
1641 ActivityManagerService.this,
1644 app.waitedForDebugger = true;
1648 if (app.waitDialog != null) {
1649 app.waitDialog.dismiss();
1650 app.waitDialog = null;
1655 case SHOW_UID_ERROR_UI_MSG: {
1657 AlertDialog d = new BaseErrorDialog(mContext);
1658 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1659 d.setCancelable(false);
1660 d.setTitle(mContext.getText(R.string.android_system_label));
1661 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1662 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1663 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1667 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1669 AlertDialog d = new BaseErrorDialog(mContext);
1670 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1671 d.setCancelable(false);
1672 d.setTitle(mContext.getText(R.string.android_system_label));
1673 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1674 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1675 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1679 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1680 synchronized (ActivityManagerService.this) {
1681 ActivityRecord ar = (ActivityRecord) msg.obj;
1682 if (mCompatModeDialog != null) {
1683 if (mCompatModeDialog.mAppInfo.packageName.equals(
1684 ar.info.applicationInfo.packageName)) {
1687 mCompatModeDialog.dismiss();
1688 mCompatModeDialog = null;
1690 if (ar != null && false) {
1691 if (mCompatModePackages.getPackageAskCompatModeLocked(
1693 int mode = mCompatModePackages.computeCompatModeLocked(
1694 ar.info.applicationInfo);
1695 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1696 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1697 mCompatModeDialog = new CompatModeDialog(
1698 ActivityManagerService.this, mContext,
1699 ar.info.applicationInfo);
1700 mCompatModeDialog.show();
1707 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1708 synchronized (ActivityManagerService.this) {
1709 final ActivityRecord ar = (ActivityRecord) msg.obj;
1710 if (mUnsupportedDisplaySizeDialog != null) {
1711 mUnsupportedDisplaySizeDialog.dismiss();
1712 mUnsupportedDisplaySizeDialog = null;
1714 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1716 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1717 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1718 mUnsupportedDisplaySizeDialog.show();
1723 case START_USER_SWITCH_UI_MSG: {
1724 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1727 case DISMISS_DIALOG_UI_MSG: {
1728 final Dialog d = (Dialog) msg.obj;
1732 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1733 dispatchProcessesChanged();
1736 case DISPATCH_PROCESS_DIED_UI_MSG: {
1737 final int pid = msg.arg1;
1738 final int uid = msg.arg2;
1739 dispatchProcessDied(pid, uid);
1742 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1743 dispatchUidsChanged();
1749 final class MainHandler extends Handler {
1750 public MainHandler(Looper looper) {
1751 super(looper, null, true);
1755 public void handleMessage(Message msg) {
1757 case UPDATE_CONFIGURATION_MSG: {
1758 final ContentResolver resolver = mContext.getContentResolver();
1759 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1762 case GC_BACKGROUND_PROCESSES_MSG: {
1763 synchronized (ActivityManagerService.this) {
1764 performAppGcsIfAppropriateLocked();
1767 case SERVICE_TIMEOUT_MSG: {
1770 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1772 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1775 mServices.serviceTimeout((ProcessRecord)msg.obj);
1777 case UPDATE_TIME_ZONE: {
1778 synchronized (ActivityManagerService.this) {
1779 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1780 ProcessRecord r = mLruProcesses.get(i);
1781 if (r.thread != null) {
1783 r.thread.updateTimeZone();
1784 } catch (RemoteException ex) {
1785 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1791 case CLEAR_DNS_CACHE_MSG: {
1792 synchronized (ActivityManagerService.this) {
1793 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794 ProcessRecord r = mLruProcesses.get(i);
1795 if (r.thread != null) {
1797 r.thread.clearDnsCache();
1798 } catch (RemoteException ex) {
1799 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1805 case UPDATE_HTTP_PROXY_MSG: {
1806 ProxyInfo proxy = (ProxyInfo)msg.obj;
1809 String exclList = "";
1810 Uri pacFileUrl = Uri.EMPTY;
1811 if (proxy != null) {
1812 host = proxy.getHost();
1813 port = Integer.toString(proxy.getPort());
1814 exclList = proxy.getExclusionListAsString();
1815 pacFileUrl = proxy.getPacFileUrl();
1817 synchronized (ActivityManagerService.this) {
1818 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1819 ProcessRecord r = mLruProcesses.get(i);
1820 if (r.thread != null) {
1822 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1823 } catch (RemoteException ex) {
1824 Slog.w(TAG, "Failed to update http proxy for: " +
1825 r.info.processName);
1831 case PROC_START_TIMEOUT_MSG: {
1834 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1836 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1839 ProcessRecord app = (ProcessRecord)msg.obj;
1840 synchronized (ActivityManagerService.this) {
1841 processStartTimedOutLocked(app);
1844 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1845 ProcessRecord app = (ProcessRecord)msg.obj;
1846 synchronized (ActivityManagerService.this) {
1847 processContentProviderPublishTimedOutLocked(app);
1850 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1851 synchronized (ActivityManagerService.this) {
1852 mActivityStarter.doPendingActivityLaunchesLocked(true);
1855 case KILL_APPLICATION_MSG: {
1856 synchronized (ActivityManagerService.this) {
1857 final int appId = msg.arg1;
1858 final int userId = msg.arg2;
1859 Bundle bundle = (Bundle)msg.obj;
1860 String pkg = bundle.getString("pkg");
1861 String reason = bundle.getString("reason");
1862 forceStopPackageLocked(pkg, appId, false, false, true, false,
1863 false, userId, reason);
1866 case FINALIZE_PENDING_INTENT_MSG: {
1867 ((PendingIntentRecord)msg.obj).completeFinalize();
1869 case POST_HEAVY_NOTIFICATION_MSG: {
1870 INotificationManager inm = NotificationManager.getService();
1875 ActivityRecord root = (ActivityRecord)msg.obj;
1876 ProcessRecord process = root.app;
1877 if (process == null) {
1882 Context context = mContext.createPackageContext(process.info.packageName, 0);
1883 String text = mContext.getString(R.string.heavy_weight_notification,
1884 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1885 Notification notification = new Notification.Builder(context)
1886 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1890 .setColor(mContext.getColor(
1891 com.android.internal.R.color.system_notification_accent_color))
1892 .setContentTitle(text)
1894 mContext.getText(R.string.heavy_weight_notification_detail))
1895 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1896 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1897 new UserHandle(root.userId)))
1900 int[] outId = new int[1];
1901 inm.enqueueNotificationWithTag("android", "android", null,
1902 R.string.heavy_weight_notification,
1903 notification, outId, root.userId);
1904 } catch (RuntimeException e) {
1905 Slog.w(ActivityManagerService.TAG,
1906 "Error showing notification for heavy-weight app", e);
1907 } catch (RemoteException e) {
1909 } catch (NameNotFoundException e) {
1910 Slog.w(TAG, "Unable to create context for heavy notification", e);
1913 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1914 INotificationManager inm = NotificationManager.getService();
1919 inm.cancelNotificationWithTag("android", null,
1920 R.string.heavy_weight_notification, msg.arg1);
1921 } catch (RuntimeException e) {
1922 Slog.w(ActivityManagerService.TAG,
1923 "Error canceling notification for service", e);
1924 } catch (RemoteException e) {
1927 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1928 synchronized (ActivityManagerService.this) {
1929 checkExcessivePowerUsageLocked(true);
1930 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1931 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1932 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1935 case REPORT_MEM_USAGE_MSG: {
1936 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1937 Thread thread = new Thread() {
1938 @Override public void run() {
1939 reportMemUsage(memInfos);
1945 case REPORT_USER_SWITCH_MSG: {
1946 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1949 case CONTINUE_USER_SWITCH_MSG: {
1950 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1953 case USER_SWITCH_TIMEOUT_MSG: {
1954 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1957 case IMMERSIVE_MODE_LOCK_MSG: {
1958 final boolean nextState = (msg.arg1 != 0);
1959 if (mUpdateLock.isHeld() != nextState) {
1960 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1961 "Applying new update lock state '" + nextState
1962 + "' for " + (ActivityRecord)msg.obj);
1964 mUpdateLock.acquire();
1966 mUpdateLock.release();
1971 case PERSIST_URI_GRANTS_MSG: {
1972 writeGrantedUriPermissions();
1975 case REQUEST_ALL_PSS_MSG: {
1976 synchronized (ActivityManagerService.this) {
1977 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1981 case START_PROFILES_MSG: {
1982 synchronized (ActivityManagerService.this) {
1983 mUserController.startProfilesLocked();
1988 synchronized (ActivityManagerService.this) {
1989 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1990 ProcessRecord r = mLruProcesses.get(i);
1991 if (r.thread != null) {
1993 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1994 } catch (RemoteException ex) {
1995 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2002 case SYSTEM_USER_START_MSG: {
2003 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2004 Integer.toString(msg.arg1), msg.arg1);
2005 mSystemServiceManager.startUser(msg.arg1);
2008 case SYSTEM_USER_UNLOCK_MSG: {
2009 final int userId = msg.arg1;
2010 mSystemServiceManager.unlockUser(userId);
2011 synchronized (ActivityManagerService.this) {
2012 mRecentTasks.loadUserRecentsLocked(userId);
2014 if (userId == UserHandle.USER_SYSTEM) {
2015 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2017 installEncryptionUnawareProviders(userId);
2018 mUserController.finishUserUnlocked((UserState) msg.obj);
2021 case SYSTEM_USER_CURRENT_MSG: {
2022 mBatteryStatsService.noteEvent(
2023 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2024 Integer.toString(msg.arg2), msg.arg2);
2025 mBatteryStatsService.noteEvent(
2026 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2027 Integer.toString(msg.arg1), msg.arg1);
2028 mSystemServiceManager.switchUser(msg.arg1);
2031 case ENTER_ANIMATION_COMPLETE_MSG: {
2032 synchronized (ActivityManagerService.this) {
2033 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2034 if (r != null && r.app != null && r.app.thread != null) {
2036 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2037 } catch (RemoteException e) {
2043 case FINISH_BOOTING_MSG: {
2044 if (msg.arg1 != 0) {
2045 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2047 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2049 if (msg.arg2 != 0) {
2050 enableScreenAfterBoot();
2054 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2056 Locale l = (Locale) msg.obj;
2057 IBinder service = ServiceManager.getService("mount");
2058 IMountService mountService = IMountService.Stub.asInterface(service);
2059 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2060 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2061 } catch (RemoteException e) {
2062 Log.e(TAG, "Error storing locale for decryption UI", e);
2066 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2067 synchronized (ActivityManagerService.this) {
2068 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2070 // Make a one-way callback to the listener
2071 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2072 } catch (RemoteException e){
2073 // Handled by the RemoteCallbackList
2076 mTaskStackListeners.finishBroadcast();
2080 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2081 synchronized (ActivityManagerService.this) {
2082 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2084 // Make a one-way callback to the listener
2085 mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2086 } catch (RemoteException e){
2087 // Handled by the RemoteCallbackList
2090 mTaskStackListeners.finishBroadcast();
2094 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2095 synchronized (ActivityManagerService.this) {
2096 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098 // Make a one-way callback to the listener
2099 mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2100 } catch (RemoteException e){
2101 // Handled by the RemoteCallbackList
2104 mTaskStackListeners.finishBroadcast();
2108 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2109 synchronized (ActivityManagerService.this) {
2110 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2112 // Make a one-way callback to the listener
2113 mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2114 } catch (RemoteException e){
2115 // Handled by the RemoteCallbackList
2118 mTaskStackListeners.finishBroadcast();
2122 case NOTIFY_FORCED_RESIZABLE_MSG: {
2123 synchronized (ActivityManagerService.this) {
2124 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2126 // Make a one-way callback to the listener
2127 mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2128 (String) msg.obj, msg.arg1);
2129 } catch (RemoteException e){
2130 // Handled by the RemoteCallbackList
2133 mTaskStackListeners.finishBroadcast();
2137 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2138 synchronized (ActivityManagerService.this) {
2139 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2141 // Make a one-way callback to the listener
2142 mTaskStackListeners.getBroadcastItem(i)
2143 .onActivityDismissingDockedStack();
2144 } catch (RemoteException e){
2145 // Handled by the RemoteCallbackList
2148 mTaskStackListeners.finishBroadcast();
2152 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2153 final int uid = msg.arg1;
2154 final byte[] firstPacket = (byte[]) msg.obj;
2156 synchronized (mPidsSelfLocked) {
2157 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2158 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2161 p.thread.notifyCleartextNetwork(firstPacket);
2162 } catch (RemoteException ignored) {
2169 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2170 final String procName;
2172 final long memLimit;
2173 final String reportPackage;
2174 synchronized (ActivityManagerService.this) {
2175 procName = mMemWatchDumpProcName;
2176 uid = mMemWatchDumpUid;
2177 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2179 val = mMemWatchProcesses.get(procName, 0);
2182 memLimit = val.first;
2183 reportPackage = val.second;
2186 reportPackage = null;
2189 if (procName == null) {
2193 if (DEBUG_PSS) Slog.d(TAG_PSS,
2194 "Showing dump heap notification from " + procName + "/" + uid);
2196 INotificationManager inm = NotificationManager.getService();
2201 String text = mContext.getString(R.string.dump_heap_notification, procName);
2204 Intent deleteIntent = new Intent();
2205 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2206 Intent intent = new Intent();
2207 intent.setClassName("android", DumpHeapActivity.class.getName());
2208 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2209 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2210 if (reportPackage != null) {
2211 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2213 int userId = UserHandle.getUserId(uid);
2214 Notification notification = new Notification.Builder(mContext)
2215 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2218 .setAutoCancel(true)
2220 .setColor(mContext.getColor(
2221 com.android.internal.R.color.system_notification_accent_color))
2222 .setContentTitle(text)
2224 mContext.getText(R.string.dump_heap_notification_detail))
2225 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2226 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2227 new UserHandle(userId)))
2228 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2229 deleteIntent, 0, UserHandle.SYSTEM))
2233 int[] outId = new int[1];
2234 inm.enqueueNotificationWithTag("android", "android", null,
2235 R.string.dump_heap_notification,
2236 notification, outId, userId);
2237 } catch (RuntimeException e) {
2238 Slog.w(ActivityManagerService.TAG,
2239 "Error showing notification for dump heap", e);
2240 } catch (RemoteException e) {
2243 case DELETE_DUMPHEAP_MSG: {
2244 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2245 DumpHeapActivity.JAVA_URI,
2246 Intent.FLAG_GRANT_READ_URI_PERMISSION
2247 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2248 UserHandle.myUserId());
2249 synchronized (ActivityManagerService.this) {
2250 mMemWatchDumpFile = null;
2251 mMemWatchDumpProcName = null;
2252 mMemWatchDumpPid = -1;
2253 mMemWatchDumpUid = -1;
2256 case FOREGROUND_PROFILE_CHANGED_MSG: {
2257 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2259 case REPORT_TIME_TRACKER_MSG: {
2260 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2261 tracker.deliverResult(mContext);
2263 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2264 mUserController.dispatchUserSwitchComplete(msg.arg1);
2266 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2267 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2269 connection.shutdown();
2270 } catch (RemoteException e) {
2271 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2273 // Only a UiAutomation can set this flag and now that
2274 // it is finished we make sure it is reset to its default.
2275 mUserIsMonkey = false;
2277 case APP_BOOST_DEACTIVATE_MSG: {
2278 synchronized(ActivityManagerService.this) {
2280 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2281 nativeMigrateFromBoost();
2283 mBoostStartTime = 0;
2285 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2286 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2291 case IDLE_UIDS_MSG: {
2294 case LOG_STACK_STATE: {
2295 synchronized (ActivityManagerService.this) {
2296 mStackSupervisor.logStackState();
2299 case VR_MODE_CHANGE_MSG: {
2300 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2301 final ActivityRecord r = (ActivityRecord) msg.obj;
2303 ComponentName requestedPackage;
2304 ComponentName callingPackage;
2306 synchronized (ActivityManagerService.this) {
2307 vrMode = r.requestedVrComponent != null;
2308 requestedPackage = r.requestedVrComponent;
2310 callingPackage = r.info.getComponentName();
2311 if (mInVrMode != vrMode) {
2313 mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2316 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2318 case VR_MODE_APPLY_IF_NEEDED_MSG: {
2319 final ActivityRecord r = (ActivityRecord) msg.obj;
2320 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2322 applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2323 r.info.getComponentName(), false);
2330 static final int COLLECT_PSS_BG_MSG = 1;
2332 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2334 public void handleMessage(Message msg) {
2336 case COLLECT_PSS_BG_MSG: {
2337 long start = SystemClock.uptimeMillis();
2338 MemInfoReader memInfo = null;
2339 synchronized (ActivityManagerService.this) {
2340 if (mFullPssPending) {
2341 mFullPssPending = false;
2342 memInfo = new MemInfoReader();
2345 if (memInfo != null) {
2346 updateCpuStatsNow();
2347 long nativeTotalPss = 0;
2348 synchronized (mProcessCpuTracker) {
2349 final int N = mProcessCpuTracker.countStats();
2350 for (int j=0; j<N; j++) {
2351 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2352 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2353 // This is definitely an application process; skip it.
2356 synchronized (mPidsSelfLocked) {
2357 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2358 // This is one of our own processes; skip it.
2362 nativeTotalPss += Debug.getPss(st.pid, null, null);
2365 memInfo.readMemInfo();
2366 synchronized (ActivityManagerService.this) {
2367 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2368 + (SystemClock.uptimeMillis()-start) + "ms");
2369 final long cachedKb = memInfo.getCachedSizeKb();
2370 final long freeKb = memInfo.getFreeSizeKb();
2371 final long zramKb = memInfo.getZramTotalSizeKb();
2372 final long kernelKb = memInfo.getKernelUsedSizeKb();
2373 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2374 kernelKb*1024, nativeTotalPss*1024);
2375 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2381 long[] tmp = new long[2];
2387 synchronized (ActivityManagerService.this) {
2388 if (mPendingPssProcesses.size() <= 0) {
2389 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2390 "Collected PSS of " + num + " processes in "
2391 + (SystemClock.uptimeMillis() - start) + "ms");
2392 mPendingPssProcesses.clear();
2395 proc = mPendingPssProcesses.remove(0);
2396 procState = proc.pssProcState;
2397 lastPssTime = proc.lastPssTime;
2398 if (proc.thread != null && procState == proc.setProcState
2399 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2400 < SystemClock.uptimeMillis()) {
2408 long pss = Debug.getPss(pid, tmp, null);
2409 synchronized (ActivityManagerService.this) {
2410 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2411 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2413 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2414 SystemClock.uptimeMillis());
2424 public void setSystemProcess() {
2426 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2427 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2428 ServiceManager.addService("meminfo", new MemBinder(this));
2429 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2430 ServiceManager.addService("dbinfo", new DbBinder(this));
2431 if (MONITOR_CPU_USAGE) {
2432 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2434 ServiceManager.addService("permission", new PermissionController(this));
2435 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2437 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2438 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2439 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2441 synchronized (this) {
2442 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2443 app.persistent = true;
2445 app.maxAdj = ProcessList.SYSTEM_ADJ;
2446 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2447 synchronized (mPidsSelfLocked) {
2448 mPidsSelfLocked.put(app.pid, app);
2450 updateLruProcessLocked(app, false, null);
2451 updateOomAdjLocked();
2453 } catch (PackageManager.NameNotFoundException e) {
2454 throw new RuntimeException(
2455 "Unable to find android system package", e);
2459 public void setWindowManager(WindowManagerService wm) {
2460 mWindowManager = wm;
2461 mStackSupervisor.setWindowManager(wm);
2462 mActivityStarter.setWindowManager(wm);
2465 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2466 mUsageStatsService = usageStatsManager;
2469 public void startObservingNativeCrashes() {
2470 final NativeCrashListener ncl = new NativeCrashListener(this);
2474 public IAppOpsService getAppOpsService() {
2475 return mAppOpsService;
2478 static class MemBinder extends Binder {
2479 ActivityManagerService mActivityManagerService;
2480 MemBinder(ActivityManagerService activityManagerService) {
2481 mActivityManagerService = activityManagerService;
2485 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2486 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2487 != PackageManager.PERMISSION_GRANTED) {
2488 pw.println("Permission Denial: can't dump meminfo from from pid="
2489 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2490 + " without permission " + android.Manifest.permission.DUMP);
2494 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2498 static class GraphicsBinder extends Binder {
2499 ActivityManagerService mActivityManagerService;
2500 GraphicsBinder(ActivityManagerService activityManagerService) {
2501 mActivityManagerService = activityManagerService;
2505 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2506 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2507 != PackageManager.PERMISSION_GRANTED) {
2508 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2509 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2510 + " without permission " + android.Manifest.permission.DUMP);
2514 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2518 static class DbBinder extends Binder {
2519 ActivityManagerService mActivityManagerService;
2520 DbBinder(ActivityManagerService activityManagerService) {
2521 mActivityManagerService = activityManagerService;
2525 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2526 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2527 != PackageManager.PERMISSION_GRANTED) {
2528 pw.println("Permission Denial: can't dump dbinfo from from pid="
2529 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2530 + " without permission " + android.Manifest.permission.DUMP);
2534 mActivityManagerService.dumpDbInfo(fd, pw, args);
2538 static class CpuBinder extends Binder {
2539 ActivityManagerService mActivityManagerService;
2540 CpuBinder(ActivityManagerService activityManagerService) {
2541 mActivityManagerService = activityManagerService;
2545 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2546 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2547 != PackageManager.PERMISSION_GRANTED) {
2548 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2549 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2550 + " without permission " + android.Manifest.permission.DUMP);
2554 synchronized (mActivityManagerService.mProcessCpuTracker) {
2555 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2556 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2557 SystemClock.uptimeMillis()));
2562 public static final class Lifecycle extends SystemService {
2563 private final ActivityManagerService mService;
2565 public Lifecycle(Context context) {
2567 mService = new ActivityManagerService(context);
2571 public void onStart() {
2575 public ActivityManagerService getService() {
2580 // Note: This method is invoked on the main thread but may need to attach various
2581 // handlers to other threads. So take care to be explicit about the looper.
2582 public ActivityManagerService(Context systemContext) {
2583 mContext = systemContext;
2584 mFactoryTest = FactoryTest.getMode();
2585 mSystemThread = ActivityThread.currentActivityThread();
2587 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2589 mHandlerThread = new ServiceThread(TAG,
2590 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2591 mHandlerThread.start();
2592 mHandler = new MainHandler(mHandlerThread.getLooper());
2593 mUiHandler = new UiHandler();
2595 /* static; one-time init here */
2596 if (sKillHandler == null) {
2597 sKillThread = new ServiceThread(TAG + ":kill",
2598 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2599 sKillThread.start();
2600 sKillHandler = new KillHandler(sKillThread.getLooper());
2603 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2604 "foreground", BROADCAST_FG_TIMEOUT, false);
2605 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2606 "background", BROADCAST_BG_TIMEOUT, true);
2607 mBroadcastQueues[0] = mFgBroadcastQueue;
2608 mBroadcastQueues[1] = mBgBroadcastQueue;
2610 mServices = new ActiveServices(this);
2611 mProviderMap = new ProviderMap(this);
2612 mAppErrors = new AppErrors(mContext, this);
2614 // TODO: Move creation of battery stats service outside of activity manager service.
2615 File dataDir = Environment.getDataDirectory();
2616 File systemDir = new File(dataDir, "system");
2618 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2619 mBatteryStatsService.getActiveStatistics().readLocked();
2620 mBatteryStatsService.scheduleWriteToDisk();
2621 mOnBattery = DEBUG_POWER ? true
2622 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2623 mBatteryStatsService.getActiveStatistics().setCallback(this);
2625 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2627 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2628 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2629 new IAppOpsCallback.Stub() {
2630 @Override public void opChanged(int op, int uid, String packageName) {
2631 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2632 if (mAppOpsService.checkOperation(op, uid, packageName)
2633 != AppOpsManager.MODE_ALLOWED) {
2634 runInBackgroundDisabled(uid);
2640 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2642 mUserController = new UserController(this);
2644 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2645 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2647 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2649 mConfiguration.setToDefaults();
2650 mConfiguration.setLocales(LocaleList.getDefault());
2652 mConfigurationSeq = mConfiguration.seq = 1;
2653 mProcessCpuTracker.init();
2655 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2656 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2657 mStackSupervisor = new ActivityStackSupervisor(this);
2658 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2659 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2661 mProcessCpuThread = new Thread("CpuTracker") {
2667 synchronized(this) {
2668 final long now = SystemClock.uptimeMillis();
2669 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2670 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2671 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2672 // + ", write delay=" + nextWriteDelay);
2673 if (nextWriteDelay < nextCpuDelay) {
2674 nextCpuDelay = nextWriteDelay;
2676 if (nextCpuDelay > 0) {
2677 mProcessCpuMutexFree.set(true);
2678 this.wait(nextCpuDelay);
2681 } catch (InterruptedException e) {
2683 updateCpuStatsNow();
2684 } catch (Exception e) {
2685 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2691 Watchdog.getInstance().addMonitor(this);
2692 Watchdog.getInstance().addThread(mHandler);
2695 public void setSystemServiceManager(SystemServiceManager mgr) {
2696 mSystemServiceManager = mgr;
2699 public void setInstaller(Installer installer) {
2700 mInstaller = installer;
2703 private void start() {
2704 Process.removeAllProcessGroups();
2705 mProcessCpuThread.start();
2707 mBatteryStatsService.publish(mContext);
2708 mAppOpsService.publish(mContext);
2709 Slog.d("AppOps", "AppOpsService published");
2710 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2713 void onUserStoppedLocked(int userId) {
2714 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2717 public void initPowerManagement() {
2718 mStackSupervisor.initPowerManagement();
2719 mBatteryStatsService.initPowerManagement();
2720 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2721 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2722 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2723 mVoiceWakeLock.setReferenceCounted(false);
2727 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2728 throws RemoteException {
2729 if (code == SYSPROPS_TRANSACTION) {
2730 // We need to tell all apps about the system property change.
2731 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2732 synchronized(this) {
2733 final int NP = mProcessNames.getMap().size();
2734 for (int ip=0; ip<NP; ip++) {
2735 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2736 final int NA = apps.size();
2737 for (int ia=0; ia<NA; ia++) {
2738 ProcessRecord app = apps.valueAt(ia);
2739 if (app.thread != null) {
2740 procs.add(app.thread.asBinder());
2746 int N = procs.size();
2747 for (int i=0; i<N; i++) {
2748 Parcel data2 = Parcel.obtain();
2750 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2751 } catch (RemoteException e) {
2757 return super.onTransact(code, data, reply, flags);
2758 } catch (RuntimeException e) {
2759 // The activity manager only throws security exceptions, so let's
2761 if (!(e instanceof SecurityException)) {
2762 Slog.wtf(TAG, "Activity Manager Crash", e);
2768 void updateCpuStats() {
2769 final long now = SystemClock.uptimeMillis();
2770 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2773 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2774 synchronized (mProcessCpuThread) {
2775 mProcessCpuThread.notify();
2780 void updateCpuStatsNow() {
2781 synchronized (mProcessCpuTracker) {
2782 mProcessCpuMutexFree.set(false);
2783 final long now = SystemClock.uptimeMillis();
2784 boolean haveNewCpuStats = false;
2786 if (MONITOR_CPU_USAGE &&
2787 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2788 mLastCpuTime.set(now);
2789 mProcessCpuTracker.update();
2790 if (mProcessCpuTracker.hasGoodLastStats()) {
2791 haveNewCpuStats = true;
2792 //Slog.i(TAG, mProcessCpu.printCurrentState());
2793 //Slog.i(TAG, "Total CPU usage: "
2794 // + mProcessCpu.getTotalCpuPercent() + "%");
2796 // Slog the cpu usage if the property is set.
2797 if ("true".equals(SystemProperties.get("events.cpu"))) {
2798 int user = mProcessCpuTracker.getLastUserTime();
2799 int system = mProcessCpuTracker.getLastSystemTime();
2800 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2801 int irq = mProcessCpuTracker.getLastIrqTime();
2802 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2803 int idle = mProcessCpuTracker.getLastIdleTime();
2805 int total = user + system + iowait + irq + softIrq + idle;
2806 if (total == 0) total = 1;
2808 EventLog.writeEvent(EventLogTags.CPU,
2809 ((user+system+iowait+irq+softIrq) * 100) / total,
2810 (user * 100) / total,
2811 (system * 100) / total,
2812 (iowait * 100) / total,
2813 (irq * 100) / total,
2814 (softIrq * 100) / total);
2819 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2820 synchronized(bstats) {
2821 synchronized(mPidsSelfLocked) {
2822 if (haveNewCpuStats) {
2823 if (bstats.startAddingCpuLocked()) {
2826 final int N = mProcessCpuTracker.countStats();
2827 for (int i=0; i<N; i++) {
2828 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2832 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2833 totalUTime += st.rel_utime;
2834 totalSTime += st.rel_stime;
2836 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2837 if (ps == null || !ps.isActive()) {
2838 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2839 pr.info.uid, pr.processName);
2841 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2842 pr.curCpuTime += st.rel_utime + st.rel_stime;
2844 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2845 if (ps == null || !ps.isActive()) {
2846 st.batteryStats = ps = bstats.getProcessStatsLocked(
2847 bstats.mapUid(st.uid), st.name);
2849 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2852 final int userTime = mProcessCpuTracker.getLastUserTime();
2853 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2854 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2855 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2856 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2857 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2858 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2859 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2864 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2865 mLastWriteTime = now;
2866 mBatteryStatsService.scheduleWriteToDisk();
2873 public void batteryNeedsCpuUpdate() {
2874 updateCpuStatsNow();
2878 public void batteryPowerChanged(boolean onBattery) {
2879 // When plugging in, update the CPU stats first before changing
2881 updateCpuStatsNow();
2882 synchronized (this) {
2883 synchronized(mPidsSelfLocked) {
2884 mOnBattery = DEBUG_POWER ? true : onBattery;
2890 public void batterySendBroadcast(Intent intent) {
2891 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2892 AppOpsManager.OP_NONE, null, false, false,
2893 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2897 * Initialize the application bind args. These are passed to each
2898 * process when the bindApplication() IPC is sent to the process. They're
2899 * lazily setup to make sure the services are running when they're asked for.
2901 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2902 // Isolated processes won't get this optimization, so that we don't
2903 // violate the rules about which services they have access to.
2905 if (mIsolatedAppBindArgs == null) {
2906 mIsolatedAppBindArgs = new HashMap<>();
2907 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2909 return mIsolatedAppBindArgs;
2912 if (mAppBindArgs == null) {
2913 mAppBindArgs = new HashMap<>();
2915 // Setup the application init args
2916 mAppBindArgs.put("package", ServiceManager.getService("package"));
2917 mAppBindArgs.put("window", ServiceManager.getService("window"));
2918 mAppBindArgs.put(Context.ALARM_SERVICE,
2919 ServiceManager.getService(Context.ALARM_SERVICE));
2921 return mAppBindArgs;
2924 boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2925 if (r == null || mFocusedActivity == r) {
2929 if (!r.isFocusable()) {
2930 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2934 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2936 final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2937 if (wasDoingSetFocusedActivity) Slog.w(TAG,
2938 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2939 mDoingSetFocusedActivity = true;
2941 final ActivityRecord last = mFocusedActivity;
2942 mFocusedActivity = r;
2943 if (r.task.isApplicationTask()) {
2944 if (mCurAppTimeTracker != r.appTimeTracker) {
2945 // We are switching app tracking. Complete the current one.
2946 if (mCurAppTimeTracker != null) {
2947 mCurAppTimeTracker.stop();
2948 mHandler.obtainMessage(
2949 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2950 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2951 mCurAppTimeTracker = null;
2953 if (r.appTimeTracker != null) {
2954 mCurAppTimeTracker = r.appTimeTracker;
2955 startTimeTrackingFocusedActivityLocked();
2958 startTimeTrackingFocusedActivityLocked();
2961 r.appTimeTracker = null;
2963 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2964 // TODO: Probably not, because we don't want to resume voice on switching
2965 // back to this activity
2966 if (r.task.voiceInteractor != null) {
2967 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2969 finishRunningVoiceLocked();
2970 IVoiceInteractionSession session;
2971 if (last != null && ((session = last.task.voiceSession) != null
2972 || (session = last.voiceSession) != null)) {
2973 // We had been in a voice interaction session, but now focused has
2974 // move to something different. Just finish the session, we can't
2975 // return to it and retain the proper state and synchronization with
2976 // the voice interaction service.
2977 finishVoiceTask(session);
2980 if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2981 mWindowManager.setFocusedApp(r.appToken, true);
2983 applyUpdateLockStateLocked(r);
2984 applyUpdateVrModeLocked(r);
2985 if (mFocusedActivity.userId != mLastFocusedUserId) {
2986 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2987 mHandler.obtainMessage(
2988 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2989 mLastFocusedUserId = mFocusedActivity.userId;
2992 // Log a warning if the focused app is changed during the process. This could
2993 // indicate a problem of the focus setting logic!
2994 if (mFocusedActivity != r) Slog.w(TAG,
2995 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2996 mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2998 EventLogTags.writeAmFocusedActivity(
2999 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3000 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3005 final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3006 if (mFocusedActivity != goingAway) {
3010 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3011 if (focusedStack != null) {
3012 final ActivityRecord top = focusedStack.topActivity();
3013 if (top != null && top.userId != mLastFocusedUserId) {
3014 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3015 mHandler.sendMessage(
3016 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3017 mLastFocusedUserId = top.userId;
3021 // Try to move focus to another activity if possible.
3022 if (setFocusedActivityLocked(
3023 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3027 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3028 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3029 mFocusedActivity = null;
3030 EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3034 public void setFocusedStack(int stackId) {
3035 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3036 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3037 final long callingId = Binder.clearCallingIdentity();
3039 synchronized (this) {
3040 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3041 if (stack == null) {
3044 final ActivityRecord r = stack.topRunningActivityLocked();
3045 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3046 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3050 Binder.restoreCallingIdentity(callingId);
3055 public void setFocusedTask(int taskId) {
3056 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3057 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3058 final long callingId = Binder.clearCallingIdentity();
3060 synchronized (this) {
3061 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3065 if (mUserController.shouldConfirmCredentials(task.userId)) {
3066 mActivityStarter.showConfirmDeviceCredential(task.userId);
3067 if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3068 mStackSupervisor.moveTaskToStackLocked(task.taskId,
3069 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3070 "setFocusedTask", ANIMATE);
3074 final ActivityRecord r = task.topRunningActivityLocked();
3075 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3076 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3080 Binder.restoreCallingIdentity(callingId);
3084 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3086 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3087 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3088 synchronized (this) {
3089 if (listener != null) {
3090 mTaskStackListeners.register(listener);
3096 public void notifyActivityDrawn(IBinder token) {
3097 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3098 synchronized (this) {
3099 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3101 r.task.stack.notifyActivityDrawnLocked(r);
3106 final void applyUpdateLockStateLocked(ActivityRecord r) {
3107 // Modifications to the UpdateLock state are done on our handler, outside
3108 // the activity manager's locks. The new state is determined based on the
3109 // state *now* of the relevant activity record. The object is passed to
3110 // the handler solely for logging detail, not to be consulted/modified.
3111 final boolean nextState = r != null && r.immersive;
3112 mHandler.sendMessage(
3113 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3116 final void applyUpdateVrModeLocked(ActivityRecord r) {
3117 mHandler.sendMessage(
3118 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3121 private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3122 mHandler.sendMessage(
3123 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3126 private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3127 ComponentName callingPackage, boolean immediate) {
3128 VrManagerInternal vrService =
3129 LocalServices.getService(VrManagerInternal.class);
3131 vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3133 vrService.setVrMode(enabled, packageName, userId, callingPackage);
3137 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3138 Message msg = Message.obtain();
3139 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3140 msg.obj = r.task.askedCompatMode ? null : r;
3141 mUiHandler.sendMessage(msg);
3144 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3145 if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3146 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3147 final Message msg = Message.obtain();
3148 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3150 mUiHandler.sendMessage(msg);
3154 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3155 String what, Object obj, ProcessRecord srcApp) {
3156 app.lastActivityTime = now;
3158 if (app.activities.size() > 0) {
3159 // Don't want to touch dependent processes that are hosting activities.
3163 int lrui = mLruProcesses.lastIndexOf(app);
3165 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3166 + what + " " + obj + " from " + srcApp);
3170 if (lrui >= index) {
3171 // Don't want to cause this to move dependent processes *back* in the
3172 // list as if they were less frequently used.
3176 if (lrui >= mLruProcessActivityStart) {
3177 // Don't want to touch dependent processes that are hosting activities.
3181 mLruProcesses.remove(lrui);
3185 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3186 + " in LRU list: " + app);
3187 mLruProcesses.add(index, app);
3191 static void killProcessGroup(int uid, int pid) {
3192 if (sKillHandler != null) {
3193 sKillHandler.sendMessage(
3194 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3196 Slog.w(TAG, "Asked to kill process group before system bringup!");
3197 Process.killProcessGroup(uid, pid);
3201 final void removeLruProcessLocked(ProcessRecord app) {
3202 int lrui = mLruProcesses.lastIndexOf(app);
3205 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3206 Process.killProcessQuiet(app.pid);
3207 killProcessGroup(app.uid, app.pid);
3209 if (lrui <= mLruProcessActivityStart) {
3210 mLruProcessActivityStart--;
3212 if (lrui <= mLruProcessServiceStart) {
3213 mLruProcessServiceStart--;
3215 mLruProcesses.remove(lrui);
3219 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3220 ProcessRecord client) {
3221 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3222 || app.treatLikeActivity;
3223 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3224 if (!activityChange && hasActivity) {
3225 // The process has activities, so we are only allowing activity-based adjustments
3226 // to move it. It should be kept in the front of the list with other
3227 // processes that have activities, and we don't want those to change their
3228 // order except due to activity operations.
3233 final long now = SystemClock.uptimeMillis();
3234 app.lastActivityTime = now;
3236 // First a quick reject: if the app is already at the position we will
3237 // put it, then there is nothing to do.
3239 final int N = mLruProcesses.size();
3240 if (N > 0 && mLruProcesses.get(N-1) == app) {
3241 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3245 if (mLruProcessServiceStart > 0
3246 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3247 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3252 int lrui = mLruProcesses.lastIndexOf(app);
3254 if (app.persistent && lrui >= 0) {
3255 // We don't care about the position of persistent processes, as long as
3256 // they are in the list.
3257 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3261 /* In progress: compute new position first, so we can avoid doing work
3262 if the process is not actually going to move. Not yet working.
3265 boolean inActivity = false, inService = false;
3267 // Process has activities, put it at the very tipsy-top.
3268 addIndex = mLruProcesses.size();
3269 nextIndex = mLruProcessServiceStart;
3271 } else if (hasService) {
3272 // Process has services, put it at the top of the service list.
3273 addIndex = mLruProcessActivityStart;
3274 nextIndex = mLruProcessServiceStart;
3278 // Process not otherwise of interest, it goes to the top of the non-service area.
3279 addIndex = mLruProcessServiceStart;
3280 if (client != null) {
3281 int clientIndex = mLruProcesses.lastIndexOf(client);
3282 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3284 if (clientIndex >= 0 && addIndex > clientIndex) {
3285 addIndex = clientIndex;
3288 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3291 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3292 + mLruProcessActivityStart + "): " + app);
3296 if (lrui < mLruProcessActivityStart) {
3297 mLruProcessActivityStart--;
3299 if (lrui < mLruProcessServiceStart) {
3300 mLruProcessServiceStart--;
3303 if (addIndex > lrui) {
3306 if (nextIndex > lrui) {
3310 mLruProcesses.remove(lrui);
3314 mLruProcesses.add(addIndex, app);
3316 mLruProcessActivityStart++;
3319 mLruProcessActivityStart++;
3325 final int N = mLruProcesses.size();
3326 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3327 // Process doesn't have activities, but has clients with
3328 // activities... move it up, but one below the top (the top
3329 // should always have a real activity).
3330 if (DEBUG_LRU) Slog.d(TAG_LRU,
3331 "Adding to second-top of LRU activity list: " + app);
3332 mLruProcesses.add(N - 1, app);
3333 // To keep it from spamming the LRU list (by making a bunch of clients),
3334 // we will push down any other entries owned by the app.
3335 final int uid = app.info.uid;
3336 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3337 ProcessRecord subProc = mLruProcesses.get(i);
3338 if (subProc.info.uid == uid) {
3339 // We want to push this one down the list. If the process after
3340 // it is for the same uid, however, don't do so, because we don't
3341 // want them internally to be re-ordered.
3342 if (mLruProcesses.get(i - 1).info.uid != uid) {
3343 if (DEBUG_LRU) Slog.d(TAG_LRU,
3344 "Pushing uid " + uid + " swapping at " + i + ": "
3345 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3346 ProcessRecord tmp = mLruProcesses.get(i);
3347 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3348 mLruProcesses.set(i - 1, tmp);
3352 // A gap, we can stop here.
3357 // Process has activities, put it at the very tipsy-top.
3358 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3359 mLruProcesses.add(app);
3361 nextIndex = mLruProcessServiceStart;
3362 } else if (hasService) {
3363 // Process has services, put it at the top of the service list.
3364 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3365 mLruProcesses.add(mLruProcessActivityStart, app);
3366 nextIndex = mLruProcessServiceStart;
3367 mLruProcessActivityStart++;
3369 // Process not otherwise of interest, it goes to the top of the non-service area.
3370 int index = mLruProcessServiceStart;
3371 if (client != null) {
3372 // If there is a client, don't allow the process to be moved up higher
3373 // in the list than that client.
3374 int clientIndex = mLruProcesses.lastIndexOf(client);
3375 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3376 + " when updating " + app);
3377 if (clientIndex <= lrui) {
3378 // Don't allow the client index restriction to push it down farther in the
3379 // list than it already is.
3382 if (clientIndex >= 0 && index > clientIndex) {
3383 index = clientIndex;
3386 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3387 mLruProcesses.add(index, app);
3388 nextIndex = index-1;
3389 mLruProcessActivityStart++;
3390 mLruProcessServiceStart++;
3393 // If the app is currently using a content provider or service,
3394 // bump those processes as well.
3395 for (int j=app.connections.size()-1; j>=0; j--) {
3396 ConnectionRecord cr = app.connections.valueAt(j);
3397 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3398 && cr.binding.service.app != null
3399 && cr.binding.service.app.lruSeq != mLruSeq
3400 && !cr.binding.service.app.persistent) {
3401 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3402 "service connection", cr, app);
3405 for (int j=app.conProviders.size()-1; j>=0; j--) {
3406 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3407 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3408 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3409 "provider reference", cpr, app);
3414 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3415 if (uid == Process.SYSTEM_UID) {
3416 // The system gets to run in any process. If there are multiple
3417 // processes with the same uid, just pick the first (this
3418 // should never happen).
3419 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3420 if (procs == null) return null;
3421 final int procCount = procs.size();
3422 for (int i = 0; i < procCount; i++) {
3423 final int procUid = procs.keyAt(i);
3424 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3425 // Don't use an app process or different user process for system component.
3428 return procs.valueAt(i);
3431 ProcessRecord proc = mProcessNames.get(processName, uid);
3432 if (false && proc != null && !keepIfLarge
3433 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3434 && proc.lastCachedPss >= 4000) {
3435 // Turn this condition on to cause killing to happen regularly, for testing.
3436 if (proc.baseProcessTracker != null) {
3437 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3439 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3440 } else if (proc != null && !keepIfLarge
3441 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3442 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3443 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3444 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3445 if (proc.baseProcessTracker != null) {
3446 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3448 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3454 void notifyPackageUse(String packageName, int reason) {
3455 IPackageManager pm = AppGlobals.getPackageManager();
3457 pm.notifyPackageUse(packageName, reason);
3458 } catch (RemoteException e) {
3462 boolean isNextTransitionForward() {
3463 int transit = mWindowManager.getPendingAppTransition();
3464 return transit == TRANSIT_ACTIVITY_OPEN
3465 || transit == TRANSIT_TASK_OPEN
3466 || transit == TRANSIT_TASK_TO_FRONT;
3469 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3470 String processName, String abiOverride, int uid, Runnable crashHandler) {
3471 synchronized(this) {
3472 ApplicationInfo info = new ApplicationInfo();
3473 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3474 // For isolated processes, the former contains the parent's uid and the latter the
3475 // actual uid of the isolated process.
3476 // In the special case introduced by this method (which is, starting an isolated
3477 // process directly from the SystemServer without an actual parent app process) the
3478 // closest thing to a parent's uid is SYSTEM_UID.
3479 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3480 // the |isolated| logic in the ProcessRecord constructor.
3481 info.uid = Process.SYSTEM_UID;
3482 info.processName = processName;
3483 info.className = entryPoint;
3484 info.packageName = "android";
3485 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3486 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3487 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3488 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3490 return proc != null ? proc.pid : 0;
3494 final ProcessRecord startProcessLocked(String processName,
3495 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3496 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3497 boolean isolated, boolean keepIfLarge) {
3498 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3499 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3500 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3501 null /* crashHandler */);
3504 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3505 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3506 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3507 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3508 long startTime = SystemClock.elapsedRealtime();
3511 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3512 checkTime(startTime, "startProcess: after getProcessRecord");
3514 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3515 // If we are in the background, then check to see if this process
3516 // is bad. If so, we will just silently fail.
3517 if (mAppErrors.isBadProcessLocked(info)) {
3518 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3519 + "/" + info.processName);
3523 // When the user is explicitly starting a process, then clear its
3524 // crash count so that we won't make it bad until they see at
3525 // least one crash dialog again, and make the process good again
3526 // if it had been bad.
3527 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3528 + "/" + info.processName);
3529 mAppErrors.resetProcessCrashTimeLocked(info);
3530 if (mAppErrors.isBadProcessLocked(info)) {
3531 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3532 UserHandle.getUserId(info.uid), info.uid,
3534 mAppErrors.clearBadProcessLocked(info);
3541 // If this is an isolated process, it can't re-use an existing process.
3545 // app launch boost for big.little configurations
3546 // use cpusets to migrate freshly launched tasks to big cores
3547 nativeMigrateToBoost();
3549 mBoostStartTime = SystemClock.uptimeMillis();
3550 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3551 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3553 // We don't have to do anything more if:
3554 // (1) There is an existing application record; and
3555 // (2) The caller doesn't think it is dead, OR there is no thread
3556 // object attached to it so we know it couldn't have crashed; and
3557 // (3) There is a pid assigned to it, so it is either starting or
3559 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3560 + " app=" + app + " knownToBeDead=" + knownToBeDead
3561 + " thread=" + (app != null ? app.thread : null)
3562 + " pid=" + (app != null ? app.pid : -1));
3563 if (app != null && app.pid > 0) {
3564 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3565 // We already have the app running, or are waiting for it to
3566 // come up (we have a pid but not yet its thread), so keep it.
3567 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3568 // If this is a new package in the process, add the package to the list
3569 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3570 checkTime(startTime, "startProcess: done, added package to proc");
3574 // An application record is attached to a previous process,
3576 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3577 checkTime(startTime, "startProcess: bad proc running, killing");
3578 killProcessGroup(app.uid, app.pid);
3579 handleAppDiedLocked(app, true, true);
3580 checkTime(startTime, "startProcess: done killing old proc");
3583 String hostingNameStr = hostingName != null
3584 ? hostingName.flattenToShortString() : null;
3587 checkTime(startTime, "startProcess: creating new process record");
3588 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3590 Slog.w(TAG, "Failed making new process record for "
3591 + processName + "/" + info.uid + " isolated=" + isolated);
3594 app.crashHandler = crashHandler;
3595 checkTime(startTime, "startProcess: done creating new process record");
3597 // If this is a new package in the process, add the package to the list
3598 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3599 checkTime(startTime, "startProcess: added package to existing proc");
3602 // If the system is not ready yet, then hold off on starting this
3603 // process until it is.
3604 if (!mProcessesReady
3605 && !isAllowedWhileBooting(info)
3606 && !allowWhileBooting) {
3607 if (!mProcessesOnHold.contains(app)) {
3608 mProcessesOnHold.add(app);
3610 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3611 "System not ready, putting on hold: " + app);
3612 checkTime(startTime, "startProcess: returning with proc on hold");
3616 checkTime(startTime, "startProcess: stepping in to startProcess");
3618 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3619 checkTime(startTime, "startProcess: done starting proc!");
3620 return (app.pid != 0) ? app : null;
3623 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3624 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3627 private final void startProcessLocked(ProcessRecord app,
3628 String hostingType, String hostingNameStr) {
3629 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3630 null /* entryPoint */, null /* entryPointArgs */);
3633 private final void startProcessLocked(ProcessRecord app, String hostingType,
3634 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3635 long startTime = SystemClock.elapsedRealtime();
3636 if (app.pid > 0 && app.pid != MY_PID) {
3637 checkTime(startTime, "startProcess: removing from pids map");
3638 synchronized (mPidsSelfLocked) {
3639 mPidsSelfLocked.remove(app.pid);
3640 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3642 checkTime(startTime, "startProcess: done removing from pids map");
3646 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3647 "startProcessLocked removing on hold: " + app);
3648 mProcessesOnHold.remove(app);
3650 checkTime(startTime, "startProcess: starting to update cpu stats");
3652 checkTime(startTime, "startProcess: done updating cpu stats");
3656 final int userId = UserHandle.getUserId(app.uid);
3657 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3658 } catch (RemoteException e) {
3659 throw e.rethrowAsRuntimeException();
3664 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3665 if (!app.isolated) {
3666 int[] permGids = null;
3668 checkTime(startTime, "startProcess: getting gids from package manager");
3669 final IPackageManager pm = AppGlobals.getPackageManager();
3670 permGids = pm.getPackageGids(app.info.packageName,
3671 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3672 MountServiceInternal mountServiceInternal = LocalServices.getService(
3673 MountServiceInternal.class);
3674 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3675 app.info.packageName);
3676 } catch (RemoteException e) {
3677 throw e.rethrowAsRuntimeException();
3681 * Add shared application and profile GIDs so applications can share some
3682 * resources like shared libraries and access user-wide resources
3684 if (ArrayUtils.isEmpty(permGids)) {
3687 gids = new int[permGids.length + 2];
3688 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3690 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3691 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3693 checkTime(startTime, "startProcess: building args");
3694 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3695 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3696 && mTopComponent != null
3697 && app.processName.equals(mTopComponent.getPackageName())) {
3700 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3701 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3706 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3707 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3708 // Also turn on CheckJNI for debuggable apps. It's quite
3709 // awkward to turn on otherwise.
3710 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3712 // Run the app in safe mode if its manifest requests so or the
3713 // system is booted in safe mode.
3714 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3715 mSafeMode == true) {
3716 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3718 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3719 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3721 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3722 if ("true".equals(genDebugInfoProperty)) {
3723 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3725 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3726 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3728 if ("1".equals(SystemProperties.get("debug.assert"))) {
3729 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3731 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3732 // Enable all debug flags required by the native debugger.
3733 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3734 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3735 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3736 mNativeDebuggingApp = null;
3739 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3740 if (requiredAbi == null) {
3741 requiredAbi = Build.SUPPORTED_ABIS[0];
3744 String instructionSet = null;
3745 if (app.info.primaryCpuAbi != null) {
3746 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3750 app.requiredAbi = requiredAbi;
3751 app.instructionSet = instructionSet;
3753 // Start the process. It will either succeed and return a result containing
3754 // the PID of the new process, or else throw a RuntimeException.
3755 boolean isActivityProcess = (entryPoint == null);
3756 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3757 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3759 checkTime(startTime, "startProcess: asking zygote to start proc");
3760 Process.ProcessStartResult startResult = Process.start(entryPoint,
3761 app.processName, uid, uid, gids, debugFlags, mountExternal,
3762 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3763 app.info.dataDir, entryPointArgs);
3764 checkTime(startTime, "startProcess: returned from zygote!");
3765 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3768 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3770 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3771 checkTime(startTime, "startProcess: done updating battery stats");
3773 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3774 UserHandle.getUserId(uid), startResult.pid, uid,
3775 app.processName, hostingType,
3776 hostingNameStr != null ? hostingNameStr : "");
3779 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3780 app.info.seinfo, app.info.sourceDir, startResult.pid);
3781 } catch (RemoteException ex) {
3785 if (app.persistent) {
3786 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3789 checkTime(startTime, "startProcess: building log message");
3790 StringBuilder buf = mStringBuilder;
3792 buf.append("Start proc ");
3793 buf.append(startResult.pid);
3795 buf.append(app.processName);
3797 UserHandle.formatUid(buf, uid);
3798 if (!isActivityProcess) {
3800 buf.append(entryPoint);
3803 buf.append(" for ");
3804 buf.append(hostingType);
3805 if (hostingNameStr != null) {
3807 buf.append(hostingNameStr);
3809 Slog.i(TAG, buf.toString());
3810 app.setPid(startResult.pid);
3811 app.usingWrapper = startResult.usingWrapper;
3812 app.removed = false;
3814 app.killedByAm = false;
3815 checkTime(startTime, "startProcess: starting to update pids map");
3816 ProcessRecord oldApp;
3817 synchronized (mPidsSelfLocked) {
3818 oldApp = mPidsSelfLocked.get(startResult.pid);
3820 // If there is already an app occupying that pid that hasn't been cleaned up
3821 if (oldApp != null && !app.isolated) {
3822 // Clean up anything relating to this pid first
3823 Slog.w(TAG, "Reusing pid " + startResult.pid
3824 + " while app is still mapped to it");
3825 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3826 true /*replacingPid*/);
3828 synchronized (mPidsSelfLocked) {
3829 this.mPidsSelfLocked.put(startResult.pid, app);
3830 if (isActivityProcess) {
3831 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3833 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3834 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3837 checkTime(startTime, "startProcess: done updating pids map");
3838 } catch (RuntimeException e) {
3839 Slog.e(TAG, "Failure starting process " + app.processName, e);
3841 // Something went very wrong while trying to start this process; one
3842 // common case is when the package is frozen due to an active
3843 // upgrade. To recover, clean up any active bookkeeping related to
3844 // starting this process. (We already invoked this method once when
3845 // the package was initially frozen through KILL_APPLICATION_MSG, so
3846 // it doesn't hurt to use it again.)
3847 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3848 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3852 void updateUsageStats(ActivityRecord component, boolean resumed) {
3853 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3854 "updateUsageStats: comp=" + component + "res=" + resumed);
3855 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3857 if (mUsageStatsService != null) {
3858 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3859 UsageEvents.Event.MOVE_TO_FOREGROUND);
3861 synchronized (stats) {
3862 stats.noteActivityResumedLocked(component.app.uid);
3865 if (mUsageStatsService != null) {
3866 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3867 UsageEvents.Event.MOVE_TO_BACKGROUND);
3869 synchronized (stats) {
3870 stats.noteActivityPausedLocked(component.app.uid);
3875 Intent getHomeIntent() {
3876 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3877 intent.setComponent(mTopComponent);
3878 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3879 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3880 intent.addCategory(Intent.CATEGORY_HOME);
3885 boolean startHomeActivityLocked(int userId, String reason) {
3886 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3887 && mTopAction == null) {
3888 // We are running in factory test mode, but unable to find
3889 // the factory test app, so just sit around displaying the
3890 // error message and don't try to start anything.
3893 Intent intent = getHomeIntent();
3894 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3895 if (aInfo != null) {
3896 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3897 // Don't do this if the home app is currently being
3899 aInfo = new ActivityInfo(aInfo);
3900 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3901 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3902 aInfo.applicationInfo.uid, true);
3903 if (app == null || app.instrumentationClass == null) {
3904 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3905 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3908 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3914 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3915 ActivityInfo ai = null;
3916 ComponentName comp = intent.getComponent();
3920 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3922 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3924 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3928 ai = info.activityInfo;
3931 } catch (RemoteException e) {
3939 * Starts the "new version setup screen" if appropriate.
3941 void startSetupActivityLocked() {
3942 // Only do this once per boot.
3943 if (mCheckedForSetup) {
3947 // We will show this screen if the current one is a different
3948 // version than the last one shown, and we are not running in
3949 // low-level factory test mode.
3950 final ContentResolver resolver = mContext.getContentResolver();
3951 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3952 Settings.Global.getInt(resolver,
3953 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3954 mCheckedForSetup = true;
3956 // See if we should be showing the platform update setup UI.
3957 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3958 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3959 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3960 if (!ris.isEmpty()) {
3961 final ResolveInfo ri = ris.get(0);
3962 String vers = ri.activityInfo.metaData != null
3963 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3965 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3966 vers = ri.activityInfo.applicationInfo.metaData.getString(
3967 Intent.METADATA_SETUP_VERSION);
3969 String lastVers = Settings.Secure.getString(
3970 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3971 if (vers != null && !vers.equals(lastVers)) {
3972 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3973 intent.setComponent(new ComponentName(
3974 ri.activityInfo.packageName, ri.activityInfo.name));
3975 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3976 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3977 null, 0, 0, 0, null, false, false, null, null, null);
3983 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3984 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3987 void enforceNotIsolatedCaller(String caller) {
3988 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3989 throw new SecurityException("Isolated process not allowed to call " + caller);
3993 void enforceShellRestriction(String restriction, int userHandle) {
3994 if (Binder.getCallingUid() == Process.SHELL_UID) {
3995 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3996 throw new SecurityException("Shell does not have permission to access user "
4003 public int getFrontActivityScreenCompatMode() {
4004 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4005 synchronized (this) {
4006 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4011 public void setFrontActivityScreenCompatMode(int mode) {
4012 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4013 "setFrontActivityScreenCompatMode");
4014 synchronized (this) {
4015 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4020 public int getPackageScreenCompatMode(String packageName) {
4021 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4022 synchronized (this) {
4023 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4028 public void setPackageScreenCompatMode(String packageName, int mode) {
4029 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4030 "setPackageScreenCompatMode");
4031 synchronized (this) {
4032 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4037 public boolean getPackageAskScreenCompat(String packageName) {
4038 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4039 synchronized (this) {
4040 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4045 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4046 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4047 "setPackageAskScreenCompat");
4048 synchronized (this) {
4049 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4053 private boolean hasUsageStatsPermission(String callingPackage) {
4054 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4055 Binder.getCallingUid(), callingPackage);
4056 if (mode == AppOpsManager.MODE_DEFAULT) {
4057 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4058 == PackageManager.PERMISSION_GRANTED;
4060 return mode == AppOpsManager.MODE_ALLOWED;
4064 public int getPackageProcessState(String packageName, String callingPackage) {
4065 if (!hasUsageStatsPermission(callingPackage)) {
4066 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4067 "getPackageProcessState");
4070 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4071 synchronized (this) {
4072 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4073 final ProcessRecord proc = mLruProcesses.get(i);
4074 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4075 || procState > proc.setProcState) {
4076 boolean found = false;
4077 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4078 if (proc.pkgList.keyAt(j).equals(packageName)) {
4079 procState = proc.setProcState;
4083 if (proc.pkgDeps != null && !found) {
4084 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4085 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4086 procState = proc.setProcState;
4098 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4099 synchronized (this) {
4100 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4104 if (app.trimMemoryLevel < level && app.thread != null &&
4105 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4106 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4108 app.thread.scheduleTrimMemory(level);
4109 app.trimMemoryLevel = level;
4111 } catch (RemoteException e) {
4112 // Fallthrough to failure case.
4119 private void dispatchProcessesChanged() {
4121 synchronized (this) {
4122 N = mPendingProcessChanges.size();
4123 if (mActiveProcessChanges.length < N) {
4124 mActiveProcessChanges = new ProcessChangeItem[N];
4126 mPendingProcessChanges.toArray(mActiveProcessChanges);
4127 mPendingProcessChanges.clear();
4128 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4129 "*** Delivering " + N + " process changes");
4132 int i = mProcessObservers.beginBroadcast();
4135 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4136 if (observer != null) {
4138 for (int j=0; j<N; j++) {
4139 ProcessChangeItem item = mActiveProcessChanges[j];
4140 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4141 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4142 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4143 + item.uid + ": " + item.foregroundActivities);
4144 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4145 item.foregroundActivities);
4147 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4148 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4149 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4150 + ": " + item.processState);
4151 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4154 } catch (RemoteException e) {
4158 mProcessObservers.finishBroadcast();
4160 synchronized (this) {
4161 for (int j=0; j<N; j++) {
4162 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4167 private void dispatchProcessDied(int pid, int uid) {
4168 int i = mProcessObservers.beginBroadcast();
4171 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4172 if (observer != null) {
4174 observer.onProcessDied(pid, uid);
4175 } catch (RemoteException e) {
4179 mProcessObservers.finishBroadcast();
4182 private void dispatchUidsChanged() {
4184 synchronized (this) {
4185 N = mPendingUidChanges.size();
4186 if (mActiveUidChanges.length < N) {
4187 mActiveUidChanges = new UidRecord.ChangeItem[N];
4189 for (int i=0; i<N; i++) {
4190 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4191 mActiveUidChanges[i] = change;
4192 if (change.uidRecord != null) {
4193 change.uidRecord.pendingChange = null;
4194 change.uidRecord = null;
4197 mPendingUidChanges.clear();
4198 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4199 "*** Delivering " + N + " uid changes");
4202 if (mLocalPowerManager != null) {
4203 for (int j=0; j<N; j++) {
4204 UidRecord.ChangeItem item = mActiveUidChanges[j];
4205 if (item.change == UidRecord.CHANGE_GONE
4206 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4207 mLocalPowerManager.uidGone(item.uid);
4209 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4214 int i = mUidObservers.beginBroadcast();
4217 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4218 final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4219 if (observer != null) {
4221 for (int j=0; j<N; j++) {
4222 UidRecord.ChangeItem item = mActiveUidChanges[j];
4223 final int change = item.change;
4224 UidRecord validateUid = null;
4225 if (VALIDATE_UID_STATES && i == 0) {
4226 validateUid = mValidateUids.get(item.uid);
4227 if (validateUid == null && change != UidRecord.CHANGE_GONE
4228 && change != UidRecord.CHANGE_GONE_IDLE) {
4229 validateUid = new UidRecord(item.uid);
4230 mValidateUids.put(item.uid, validateUid);
4233 if (change == UidRecord.CHANGE_IDLE
4234 || change == UidRecord.CHANGE_GONE_IDLE) {
4235 if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4236 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4237 "UID idle uid=" + item.uid);
4238 observer.onUidIdle(item.uid);
4240 if (VALIDATE_UID_STATES && i == 0) {
4241 if (validateUid != null) {
4242 validateUid.idle = true;
4245 } else if (change == UidRecord.CHANGE_ACTIVE) {
4246 if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4247 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4248 "UID active uid=" + item.uid);
4249 observer.onUidActive(item.uid);
4251 if (VALIDATE_UID_STATES && i == 0) {
4252 validateUid.idle = false;
4255 if (change == UidRecord.CHANGE_GONE
4256 || change == UidRecord.CHANGE_GONE_IDLE) {
4257 if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4258 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4259 "UID gone uid=" + item.uid);
4260 observer.onUidGone(item.uid);
4262 if (VALIDATE_UID_STATES && i == 0) {
4263 if (validateUid != null) {
4264 mValidateUids.remove(item.uid);
4268 if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4269 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4270 "UID CHANGED uid=" + item.uid
4271 + ": " + item.processState);
4272 observer.onUidStateChanged(item.uid, item.processState);
4274 if (VALIDATE_UID_STATES && i == 0) {
4275 validateUid.curProcState = validateUid.setProcState
4276 = item.processState;
4280 } catch (RemoteException e) {
4284 mUidObservers.finishBroadcast();
4286 synchronized (this) {
4287 for (int j=0; j<N; j++) {
4288 mAvailUidChanges.add(mActiveUidChanges[j]);
4294 public final int startActivity(IApplicationThread caller, String callingPackage,
4295 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4296 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4297 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4298 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4299 UserHandle.getCallingUserId());
4302 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4303 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4304 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4305 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4306 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4308 // TODO: Switch to user app stacks here.
4309 String mimeType = intent.getType();
4310 final Uri data = intent.getData();
4311 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4312 mimeType = getProviderMimeType(data, userId);
4314 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4316 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4317 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4318 null, 0, 0, null, null, null, null, false, userId, container, null);
4322 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4323 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4324 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4325 enforceNotIsolatedCaller("startActivity");
4326 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4327 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4328 // TODO: Switch to user app stacks here.
4329 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4330 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4331 profilerInfo, null, null, bOptions, false, userId, null, null);
4335 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4336 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4337 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4340 // This is very dangerous -- it allows you to perform a start activity (including
4341 // permission grants) as any app that may launch one of your own activities. So
4342 // we will only allow this to be done from activities that are part of the core framework,
4343 // and then only when they are running as the system.
4344 final ActivityRecord sourceRecord;
4345 final int targetUid;
4346 final String targetPackage;
4347 synchronized (this) {
4348 if (resultTo == null) {
4349 throw new SecurityException("Must be called from an activity");
4351 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4352 if (sourceRecord == null) {
4353 throw new SecurityException("Called with bad activity token: " + resultTo);
4355 if (!sourceRecord.info.packageName.equals("android")) {
4356 throw new SecurityException(
4357 "Must be called from an activity that is declared in the android package");
4359 if (sourceRecord.app == null) {
4360 throw new SecurityException("Called without a process attached to activity");
4362 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4363 // This is still okay, as long as this activity is running under the
4364 // uid of the original calling activity.
4365 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4366 throw new SecurityException(
4367 "Calling activity in uid " + sourceRecord.app.uid
4368 + " must be system uid or original calling uid "
4369 + sourceRecord.launchedFromUid);
4372 if (ignoreTargetSecurity) {
4373 if (intent.getComponent() == null) {
4374 throw new SecurityException(
4375 "Component must be specified with ignoreTargetSecurity");
4377 if (intent.getSelector() != null) {
4378 throw new SecurityException(
4379 "Selector not allowed with ignoreTargetSecurity");
4382 targetUid = sourceRecord.launchedFromUid;
4383 targetPackage = sourceRecord.launchedFromPackage;
4386 if (userId == UserHandle.USER_NULL) {
4387 userId = UserHandle.getUserId(sourceRecord.app.uid);
4390 // TODO: Switch to user app stacks here.
4392 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4393 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4394 null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4396 } catch (SecurityException e) {
4397 // XXX need to figure out how to propagate to original app.
4398 // A SecurityException here is generally actually a fault of the original
4399 // calling activity (such as a fairly granting permissions), so propagate it
4402 StringBuilder msg = new StringBuilder();
4403 msg.append("While launching");
4404 msg.append(intent.toString());
4406 msg.append(e.getMessage());
4413 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4414 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4415 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4416 enforceNotIsolatedCaller("startActivityAndWait");
4417 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4418 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4419 WaitResult res = new WaitResult();
4420 // TODO: Switch to user app stacks here.
4421 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4422 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4423 bOptions, false, userId, null, null);
4428 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4429 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4430 int startFlags, Configuration config, Bundle bOptions, int userId) {
4431 enforceNotIsolatedCaller("startActivityWithConfig");
4432 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4433 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4434 // TODO: Switch to user app stacks here.
4435 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4436 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4437 null, null, config, bOptions, false, userId, null, null);
4442 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4443 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4444 int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4445 throws TransactionTooLargeException {
4446 enforceNotIsolatedCaller("startActivityIntentSender");
4447 // Refuse possible leaked file descriptors
4448 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4449 throw new IllegalArgumentException("File descriptors passed in Intent");
4452 IIntentSender sender = intent.getTarget();
4453 if (!(sender instanceof PendingIntentRecord)) {
4454 throw new IllegalArgumentException("Bad PendingIntent object");
4457 PendingIntentRecord pir = (PendingIntentRecord)sender;
4459 synchronized (this) {
4460 // If this is coming from the currently resumed activity, it is
4461 // effectively saying that app switches are allowed at this point.
4462 final ActivityStack stack = getFocusedStack();
4463 if (stack.mResumedActivity != null &&
4464 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4465 mAppSwitchesAllowedTime = 0;
4468 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4469 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4474 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4475 Intent intent, String resolvedType, IVoiceInteractionSession session,
4476 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4477 Bundle bOptions, int userId) {
4478 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4479 != PackageManager.PERMISSION_GRANTED) {
4480 String msg = "Permission Denial: startVoiceActivity() from pid="
4481 + Binder.getCallingPid()
4482 + ", uid=" + Binder.getCallingUid()
4483 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4485 throw new SecurityException(msg);
4487 if (session == null || interactor == null) {
4488 throw new NullPointerException("null session or interactor");
4490 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4491 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4492 // TODO: Switch to user app stacks here.
4493 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4494 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4495 null, bOptions, false, userId, null, null);
4499 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4500 throws RemoteException {
4501 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4502 synchronized (this) {
4503 ActivityRecord activity = getFocusedStack().topActivity();
4504 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4505 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4507 if (mRunningVoice != null || activity.task.voiceSession != null
4508 || activity.voiceSession != null) {
4509 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4512 if (activity.pendingVoiceInteractionStart) {
4513 Slog.w(TAG, "Pending start of voice interaction already.");
4516 activity.pendingVoiceInteractionStart = true;
4518 LocalServices.getService(VoiceInteractionManagerInternal.class)
4519 .startLocalVoiceInteraction(callingActivity, options);
4523 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4524 LocalServices.getService(VoiceInteractionManagerInternal.class)
4525 .stopLocalVoiceInteraction(callingActivity);
4529 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4530 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4531 .supportsLocalVoiceInteraction();
4534 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4535 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4536 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4537 if (activityToCallback == null) return;
4538 activityToCallback.setVoiceSessionLocked(voiceSession);
4540 // Inform the activity
4542 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4544 long token = Binder.clearCallingIdentity();
4546 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4548 Binder.restoreCallingIdentity(token);
4550 // TODO: VI Should we cache the activity so that it's easier to find later
4551 // rather than scan through all the stacks and activities?
4552 } catch (RemoteException re) {
4553 activityToCallback.clearVoiceSessionLocked();
4554 // TODO: VI Should this terminate the voice session?
4559 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4560 synchronized (this) {
4561 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4563 mVoiceWakeLock.acquire();
4565 mVoiceWakeLock.release();
4572 public boolean startNextMatchingActivity(IBinder callingActivity,
4573 Intent intent, Bundle bOptions) {
4574 // Refuse possible leaked file descriptors
4575 if (intent != null && intent.hasFileDescriptors() == true) {
4576 throw new IllegalArgumentException("File descriptors passed in Intent");
4578 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4580 synchronized (this) {
4581 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4583 ActivityOptions.abort(options);
4586 if (r.app == null || r.app.thread == null) {
4587 // The caller is not running... d'oh!
4588 ActivityOptions.abort(options);
4591 intent = new Intent(intent);
4592 // The caller is not allowed to change the data.
4593 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4594 // And we are resetting to find the next component...
4595 intent.setComponent(null);
4597 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4599 ActivityInfo aInfo = null;
4601 List<ResolveInfo> resolves =
4602 AppGlobals.getPackageManager().queryIntentActivities(
4603 intent, r.resolvedType,
4604 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4605 UserHandle.getCallingUserId()).getList();
4607 // Look for the original activity in the list...
4608 final int N = resolves != null ? resolves.size() : 0;
4609 for (int i=0; i<N; i++) {
4610 ResolveInfo rInfo = resolves.get(i);
4611 if (rInfo.activityInfo.packageName.equals(r.packageName)
4612 && rInfo.activityInfo.name.equals(r.info.name)) {
4613 // We found the current one... the next matching is
4617 aInfo = resolves.get(i).activityInfo;
4620 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4621 + "/" + r.info.name);
4622 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4623 ? "null" : aInfo.packageName + "/" + aInfo.name));
4628 } catch (RemoteException e) {
4631 if (aInfo == null) {
4632 // Nobody who is next!
4633 ActivityOptions.abort(options);
4634 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4638 intent.setComponent(new ComponentName(
4639 aInfo.applicationInfo.packageName, aInfo.name));
4640 intent.setFlags(intent.getFlags()&~(
4641 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4642 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4643 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4644 Intent.FLAG_ACTIVITY_NEW_TASK));
4646 // Okay now we need to start the new activity, replacing the
4647 // currently running activity. This is a little tricky because
4648 // we want to start the new one as if the current one is finished,
4649 // but not finish the current one first so that there is no flicker.
4651 final boolean wasFinishing = r.finishing;
4654 // Propagate reply information over to the new activity.
4655 final ActivityRecord resultTo = r.resultTo;
4656 final String resultWho = r.resultWho;
4657 final int requestCode = r.requestCode;
4659 if (resultTo != null) {
4660 resultTo.removeResultsLocked(r, resultWho, requestCode);
4663 final long origId = Binder.clearCallingIdentity();
4664 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4665 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4666 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4667 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4668 false, false, null, null, null);
4669 Binder.restoreCallingIdentity(origId);
4671 r.finishing = wasFinishing;
4672 if (res != ActivityManager.START_SUCCESS) {
4680 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4681 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4682 String msg = "Permission Denial: startActivityFromRecents called without " +
4683 START_TASKS_FROM_RECENTS;
4685 throw new SecurityException(msg);
4687 final long origId = Binder.clearCallingIdentity();
4689 synchronized (this) {
4690 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4693 Binder.restoreCallingIdentity(origId);
4697 final int startActivityInPackage(int uid, String callingPackage,
4698 Intent intent, String resolvedType, IBinder resultTo,
4699 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4700 IActivityContainer container, TaskRecord inTask) {
4702 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4703 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4705 // TODO: Switch to user app stacks here.
4706 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4707 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4708 null, null, null, bOptions, false, userId, container, inTask);
4713 public final int startActivities(IApplicationThread caller, String callingPackage,
4714 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4716 enforceNotIsolatedCaller("startActivities");
4717 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4718 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4719 // TODO: Switch to user app stacks here.
4720 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4721 resolvedTypes, resultTo, bOptions, userId);
4725 final int startActivitiesInPackage(int uid, String callingPackage,
4726 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4727 Bundle bOptions, int userId) {
4729 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4730 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4731 // TODO: Switch to user app stacks here.
4732 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4733 resultTo, bOptions, userId);
4738 public void reportActivityFullyDrawn(IBinder token) {
4739 synchronized (this) {
4740 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4744 r.reportFullyDrawnLocked();
4749 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4750 synchronized (this) {
4751 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4755 TaskRecord task = r.task;
4756 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4757 // Fixed screen orientation isn't supported when activities aren't in full screen
4761 final long origId = Binder.clearCallingIdentity();
4762 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4763 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4764 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4765 if (config != null) {
4766 r.frozenBeforeDestroy = true;
4767 if (!updateConfigurationLocked(config, r, false)) {
4768 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4771 Binder.restoreCallingIdentity(origId);
4776 public int getRequestedOrientation(IBinder token) {
4777 synchronized (this) {
4778 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4780 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4782 return mWindowManager.getAppOrientation(r.appToken);
4787 * This is the internal entry point for handling Activity.finish().
4789 * @param token The Binder token referencing the Activity we want to finish.
4790 * @param resultCode Result code, if any, from this Activity.
4791 * @param resultData Result data (Intent), if any, from this Activity.
4792 * @param finishTask Whether to finish the task associated with this Activity.
4794 * @return Returns true if the activity successfully finished, or false if it is still running.
4797 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4799 // Refuse possible leaked file descriptors
4800 if (resultData != null && resultData.hasFileDescriptors() == true) {
4801 throw new IllegalArgumentException("File descriptors passed in Intent");
4804 synchronized(this) {
4805 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4809 // Keep track of the root activity of the task before we finish it
4810 TaskRecord tr = r.task;
4811 ActivityRecord rootR = tr.getRootActivity();
4812 if (rootR == null) {
4813 Slog.w(TAG, "Finishing task with all activities already finished");
4815 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4817 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4818 mStackSupervisor.isLastLockedTask(tr)) {
4819 Slog.i(TAG, "Not finishing task in lock task mode");
4820 mStackSupervisor.showLockTaskToast();
4823 if (mController != null) {
4824 // Find the first activity that is not finishing.
4825 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4827 // ask watcher if this is allowed
4828 boolean resumeOK = true;
4830 resumeOK = mController.activityResuming(next.packageName);
4831 } catch (RemoteException e) {
4833 Watchdog.getInstance().setActivityController(null);
4837 Slog.i(TAG, "Not finishing activity because controller resumed");
4842 final long origId = Binder.clearCallingIdentity();
4845 final boolean finishWithRootActivity =
4846 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4847 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4848 || (finishWithRootActivity && r == rootR)) {
4849 // If requested, remove the task that is associated to this activity only if it
4850 // was the root activity in the task. The result code and data is ignored
4851 // because we don't support returning them across task boundaries. Also, to
4852 // keep backwards compatibility we remove the task from recents when finishing
4853 // task with root activity.
4854 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4856 Slog.i(TAG, "Removing task failed to finish activity");
4859 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4860 resultData, "app-request", true);
4862 Slog.i(TAG, "Failed to finish by app-request");
4867 Binder.restoreCallingIdentity(origId);
4873 public final void finishHeavyWeightApp() {
4874 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4875 != PackageManager.PERMISSION_GRANTED) {
4876 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4877 + Binder.getCallingPid()
4878 + ", uid=" + Binder.getCallingUid()
4879 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4881 throw new SecurityException(msg);
4884 synchronized(this) {
4885 if (mHeavyWeightProcess == null) {
4889 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4890 for (int i = 0; i < activities.size(); i++) {
4891 ActivityRecord r = activities.get(i);
4892 if (!r.finishing && r.isInStackLocked()) {
4893 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4894 null, "finish-heavy", true);
4898 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4899 mHeavyWeightProcess.userId, 0));
4900 mHeavyWeightProcess = null;
4905 public void crashApplication(int uid, int initialPid, String packageName,
4907 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4908 != PackageManager.PERMISSION_GRANTED) {
4909 String msg = "Permission Denial: crashApplication() from pid="
4910 + Binder.getCallingPid()
4911 + ", uid=" + Binder.getCallingUid()
4912 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4914 throw new SecurityException(msg);
4917 synchronized(this) {
4918 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4923 public final void finishSubActivity(IBinder token, String resultWho,
4925 synchronized(this) {
4926 final long origId = Binder.clearCallingIdentity();
4927 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4929 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4931 Binder.restoreCallingIdentity(origId);
4936 public boolean finishActivityAffinity(IBinder token) {
4937 synchronized(this) {
4938 final long origId = Binder.clearCallingIdentity();
4940 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4945 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4947 final TaskRecord task = r.task;
4948 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4949 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4950 mStackSupervisor.showLockTaskToast();
4953 return task.stack.finishActivityAffinityLocked(r);
4955 Binder.restoreCallingIdentity(origId);
4961 public void finishVoiceTask(IVoiceInteractionSession session) {
4962 synchronized (this) {
4963 final long origId = Binder.clearCallingIdentity();
4965 // TODO: VI Consider treating local voice interactions and voice tasks
4967 mStackSupervisor.finishVoiceTask(session);
4969 Binder.restoreCallingIdentity(origId);
4976 public boolean releaseActivityInstance(IBinder token) {
4977 synchronized(this) {
4978 final long origId = Binder.clearCallingIdentity();
4980 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4984 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4986 Binder.restoreCallingIdentity(origId);
4992 public void releaseSomeActivities(IApplicationThread appInt) {
4993 synchronized(this) {
4994 final long origId = Binder.clearCallingIdentity();
4996 ProcessRecord app = getRecordForAppLocked(appInt);
4997 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4999 Binder.restoreCallingIdentity(origId);
5005 public boolean willActivityBeVisible(IBinder token) {
5006 synchronized(this) {
5007 ActivityStack stack = ActivityRecord.getStackLocked(token);
5008 if (stack != null) {
5009 return stack.willActivityBeVisibleLocked(token);
5016 public void overridePendingTransition(IBinder token, String packageName,
5017 int enterAnim, int exitAnim) {
5018 synchronized(this) {
5019 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5024 final long origId = Binder.clearCallingIdentity();
5026 if (self.state == ActivityState.RESUMED
5027 || self.state == ActivityState.PAUSING) {
5028 mWindowManager.overridePendingAppTransition(packageName,
5029 enterAnim, exitAnim, null);
5032 Binder.restoreCallingIdentity(origId);
5037 * Main function for removing an existing process from the activity manager
5038 * as a result of that process going away. Clears out all connections
5041 private final void handleAppDiedLocked(ProcessRecord app,
5042 boolean restarting, boolean allowRestart) {
5044 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5045 false /*replacingPid*/);
5046 if (!kept && !restarting) {
5047 removeLruProcessLocked(app);
5049 ProcessList.remove(pid);
5053 if (mProfileProc == app) {
5054 clearProfilerLocked();
5057 // Remove this application's activities from active lists.
5058 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5060 app.activities.clear();
5062 if (app.instrumentationClass != null) {
5063 Slog.w(TAG, "Crash of app " + app.processName
5064 + " running instrumentation " + app.instrumentationClass);
5065 Bundle info = new Bundle();
5066 info.putString("shortMsg", "Process crashed.");
5067 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5070 if (!restarting && hasVisibleActivities
5071 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5072 // If there was nothing to resume, and we are not already restarting this process, but
5073 // there is a visible activity that is hosted by the process... then make sure all
5074 // visible activities are running, taking care of restarting this process.
5075 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5079 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5080 IBinder threadBinder = thread.asBinder();
5081 // Find the application record.
5082 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5083 ProcessRecord rec = mLruProcesses.get(i);
5084 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5091 final ProcessRecord getRecordForAppLocked(
5092 IApplicationThread thread) {
5093 if (thread == null) {
5097 int appIndex = getLRURecordIndexForAppLocked(thread);
5098 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5101 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5102 // If there are no longer any background processes running,
5103 // and the app that died was not running instrumentation,
5104 // then tell everyone we are now low on memory.
5105 boolean haveBg = false;
5106 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5107 ProcessRecord rec = mLruProcesses.get(i);
5108 if (rec.thread != null
5109 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5116 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5118 long now = SystemClock.uptimeMillis();
5119 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5122 mLastMemUsageReportTime = now;
5125 final ArrayList<ProcessMemInfo> memInfos
5126 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5127 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5128 long now = SystemClock.uptimeMillis();
5129 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5130 ProcessRecord rec = mLruProcesses.get(i);
5131 if (rec == dyingProc || rec.thread == null) {
5135 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5136 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5138 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5139 // The low memory report is overriding any current
5140 // state for a GC request. Make sure to do
5141 // heavy/important/visible/foreground processes first.
5142 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5143 rec.lastRequestedGc = 0;
5145 rec.lastRequestedGc = rec.lastLowMemory;
5147 rec.reportLowMemory = true;
5148 rec.lastLowMemory = now;
5149 mProcessesToGc.remove(rec);
5150 addProcessToGcListLocked(rec);
5154 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5155 mHandler.sendMessage(msg);
5157 scheduleAppGcsLocked();
5161 final void appDiedLocked(ProcessRecord app) {
5162 appDiedLocked(app, app.pid, app.thread, false);
5165 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5166 boolean fromBinderDied) {
5167 // First check if this ProcessRecord is actually active for the pid.
5168 synchronized (mPidsSelfLocked) {
5169 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5170 if (curProc != app) {
5171 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5176 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5177 synchronized (stats) {
5178 stats.noteProcessDiedLocked(app.info.uid, pid);
5182 if (!fromBinderDied) {
5183 Process.killProcessQuiet(pid);
5185 killProcessGroup(app.uid, pid);
5189 // Clean up already done if the process has been re-started.
5190 if (app.pid == pid && app.thread != null &&
5191 app.thread.asBinder() == thread.asBinder()) {
5192 boolean doLowMem = app.instrumentationClass == null;
5193 boolean doOomAdj = doLowMem;
5194 if (!app.killedByAm) {
5195 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5197 mAllowLowerMemLevel = true;
5199 // Note that we always want to do oom adj to update our state with the
5200 // new number of procs.
5201 mAllowLowerMemLevel = false;
5204 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5205 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5206 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5207 handleAppDiedLocked(app, false, true);
5210 updateOomAdjLocked();
5213 doLowMemReportIfNeededLocked(app);
5215 } else if (app.pid != pid) {
5216 // A new process has already been started.
5217 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5218 + ") has died and restarted (pid " + app.pid + ").");
5219 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5220 } else if (DEBUG_PROCESSES) {
5221 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5222 + thread.asBinder());
5227 * If a stack trace dump file is configured, dump process stack traces.
5228 * @param clearTraces causes the dump file to be erased prior to the new
5229 * traces being written, if true; when false, the new traces will be
5230 * appended to any existing file content.
5231 * @param firstPids of dalvik VM processes to dump stack traces for first
5232 * @param lastPids of dalvik VM processes to dump stack traces for last
5233 * @param nativeProcs optional list of native process names to dump stack crawls
5234 * @return file containing stack traces, or null if no dump file is configured
5236 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5237 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5238 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5239 if (tracesPath == null || tracesPath.length() == 0) {
5243 File tracesFile = new File(tracesPath);
5245 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5246 tracesFile.createNewFile();
5247 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5248 } catch (IOException e) {
5249 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5253 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5257 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5258 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5259 // Use a FileObserver to detect when traces finish writing.
5260 // The order of traces is considered important to maintain for legibility.
5261 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5263 public synchronized void onEvent(int event, String path) { notify(); }
5267 observer.startWatching();
5269 // First collect all of the stacks of the most important pids.
5270 if (firstPids != null) {
5272 int num = firstPids.size();
5273 for (int i = 0; i < num; i++) {
5274 synchronized (observer) {
5275 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5276 + firstPids.get(i));
5277 final long sime = SystemClock.elapsedRealtime();
5278 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5279 observer.wait(1000); // Wait for write-close, give up after 1 sec
5280 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5281 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5284 } catch (InterruptedException e) {
5289 // Next collect the stacks of the native pids
5290 if (nativeProcs != null) {
5291 int[] pids = Process.getPidsForCommands(nativeProcs);
5293 for (int pid : pids) {
5294 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5295 final long sime = SystemClock.elapsedRealtime();
5296 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5297 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5298 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5303 // Lastly, measure CPU usage.
5304 if (processCpuTracker != null) {
5305 processCpuTracker.init();
5307 processCpuTracker.update();
5309 synchronized (processCpuTracker) {
5310 processCpuTracker.wait(500); // measure over 1/2 second.
5312 } catch (InterruptedException e) {
5314 processCpuTracker.update();
5316 // We'll take the stack crawls of just the top apps using CPU.
5317 final int N = processCpuTracker.countWorkingStats();
5319 for (int i=0; i<N && numProcs<5; i++) {
5320 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5321 if (lastPids.indexOfKey(stats.pid) >= 0) {
5324 synchronized (observer) {
5325 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5327 final long stime = SystemClock.elapsedRealtime();
5328 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5329 observer.wait(1000); // Wait for write-close, give up after 1 sec
5330 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5331 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5333 } catch (InterruptedException e) {
5336 } else if (DEBUG_ANR) {
5337 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5343 observer.stopWatching();
5347 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5348 if (true || IS_USER_BUILD) {
5351 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5352 if (tracesPath == null || tracesPath.length() == 0) {
5356 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5357 StrictMode.allowThreadDiskWrites();
5359 final File tracesFile = new File(tracesPath);
5360 final File tracesDir = tracesFile.getParentFile();
5361 final File tracesTmp = new File(tracesDir, "__tmp__");
5363 if (tracesFile.exists()) {
5365 tracesFile.renameTo(tracesTmp);
5367 StringBuilder sb = new StringBuilder();
5368 Time tobj = new Time();
5369 tobj.set(System.currentTimeMillis());
5370 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5372 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5373 sb.append(" since ");
5375 FileOutputStream fos = new FileOutputStream(tracesFile);
5376 fos.write(sb.toString().getBytes());
5378 fos.write("\n*** No application process!".getBytes());
5381 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5382 } catch (IOException e) {
5383 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5388 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5389 firstPids.add(app.pid);
5390 dumpStackTraces(tracesPath, firstPids, null, null, null);
5393 File lastTracesFile = null;
5394 File curTracesFile = null;
5395 for (int i=9; i>=0; i--) {
5396 String name = String.format(Locale.US, "slow%02d.txt", i);
5397 curTracesFile = new File(tracesDir, name);
5398 if (curTracesFile.exists()) {
5399 if (lastTracesFile != null) {
5400 curTracesFile.renameTo(lastTracesFile);
5402 curTracesFile.delete();
5405 lastTracesFile = curTracesFile;
5407 tracesFile.renameTo(curTracesFile);
5408 if (tracesTmp.exists()) {
5409 tracesTmp.renameTo(tracesFile);
5412 StrictMode.setThreadPolicy(oldPolicy);
5416 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5417 if (!mLaunchWarningShown) {
5418 mLaunchWarningShown = true;
5419 mUiHandler.post(new Runnable() {
5422 synchronized (ActivityManagerService.this) {
5423 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5425 mUiHandler.postDelayed(new Runnable() {
5428 synchronized (ActivityManagerService.this) {
5430 mLaunchWarningShown = false;
5441 public boolean clearApplicationUserData(final String packageName,
5442 final IPackageDataObserver observer, int userId) {
5443 enforceNotIsolatedCaller("clearApplicationUserData");
5444 int uid = Binder.getCallingUid();
5445 int pid = Binder.getCallingPid();
5446 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5447 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5450 long callingId = Binder.clearCallingIdentity();
5452 IPackageManager pm = AppGlobals.getPackageManager();
5454 synchronized(this) {
5455 if (getPackageManagerInternalLocked().canPackageBeWiped(
5456 userId, packageName)) {
5457 throw new SecurityException(
5458 "Cannot clear data for a device owner or a profile owner");
5462 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5463 } catch (RemoteException e) {
5466 Slog.w(TAG, "Invalid packageName: " + packageName);
5467 if (observer != null) {
5469 observer.onRemoveCompleted(packageName, false);
5470 } catch (RemoteException e) {
5471 Slog.i(TAG, "Observer no longer exists.");
5476 if (uid == pkgUid || checkComponentPermission(
5477 android.Manifest.permission.CLEAR_APP_USER_DATA,
5479 == PackageManager.PERMISSION_GRANTED) {
5480 forceStopPackageLocked(packageName, pkgUid, "clear data");
5482 throw new SecurityException("PID " + pid + " does not have permission "
5483 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5484 + " of package " + packageName);
5487 // Remove all tasks match the cleared application package and user
5488 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5489 final TaskRecord tr = mRecentTasks.get(i);
5490 final String taskPackageName =
5491 tr.getBaseIntent().getComponent().getPackageName();
5492 if (tr.userId != userId) continue;
5493 if (!taskPackageName.equals(packageName)) continue;
5494 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5498 final int pkgUidF = pkgUid;
5499 final int userIdF = userId;
5500 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5502 public void onRemoveCompleted(String packageName, boolean succeeded)
5503 throws RemoteException {
5504 synchronized (ActivityManagerService.this) {
5505 finishForceStopPackageLocked(packageName, pkgUidF);
5508 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5509 Uri.fromParts("package", packageName, null));
5510 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5511 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5512 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5513 null, null, 0, null, null, null, null, false, false, userIdF);
5515 if (observer != null) {
5516 observer.onRemoveCompleted(packageName, succeeded);
5522 // Clear application user data
5523 pm.clearApplicationUserData(packageName, localObserver, userId);
5525 synchronized(this) {
5526 // Remove all permissions granted from/to this package
5527 removeUriPermissionsForPackageLocked(packageName, userId, true);
5530 // Remove all zen rules created by this package; revoke it's zen access.
5531 INotificationManager inm = NotificationManager.getService();
5532 inm.removeAutomaticZenRules(packageName);
5533 inm.setNotificationPolicyAccessGranted(packageName, false);
5535 } catch (RemoteException e) {
5538 Binder.restoreCallingIdentity(callingId);
5544 public void killBackgroundProcesses(final String packageName, int userId) {
5545 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5546 != PackageManager.PERMISSION_GRANTED &&
5547 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5548 != PackageManager.PERMISSION_GRANTED) {
5549 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5550 + Binder.getCallingPid()
5551 + ", uid=" + Binder.getCallingUid()
5552 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5554 throw new SecurityException(msg);
5557 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5558 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5559 long callingId = Binder.clearCallingIdentity();
5561 IPackageManager pm = AppGlobals.getPackageManager();
5562 synchronized(this) {
5565 appId = UserHandle.getAppId(
5566 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5567 } catch (RemoteException e) {
5570 Slog.w(TAG, "Invalid packageName: " + packageName);
5573 killPackageProcessesLocked(packageName, appId, userId,
5574 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5577 Binder.restoreCallingIdentity(callingId);
5582 public void killAllBackgroundProcesses() {
5583 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5584 != PackageManager.PERMISSION_GRANTED) {
5585 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5586 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5587 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5589 throw new SecurityException(msg);
5592 final long callingId = Binder.clearCallingIdentity();
5594 synchronized (this) {
5595 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5596 final int NP = mProcessNames.getMap().size();
5597 for (int ip = 0; ip < NP; ip++) {
5598 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5599 final int NA = apps.size();
5600 for (int ia = 0; ia < NA; ia++) {
5601 final ProcessRecord app = apps.valueAt(ia);
5602 if (app.persistent) {
5603 // We don't kill persistent processes.
5608 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5615 final int N = procs.size();
5616 for (int i = 0; i < N; i++) {
5617 removeProcessLocked(procs.get(i), false, true, "kill all background");
5620 mAllowLowerMemLevel = true;
5622 updateOomAdjLocked();
5623 doLowMemReportIfNeededLocked(null);
5626 Binder.restoreCallingIdentity(callingId);
5631 * Kills all background processes, except those matching any of the
5632 * specified properties.
5634 * @param minTargetSdk the target SDK version at or above which to preserve
5635 * processes, or {@code -1} to ignore the target SDK
5636 * @param maxProcState the process state at or below which to preserve
5637 * processes, or {@code -1} to ignore the process state
5639 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5640 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5641 != PackageManager.PERMISSION_GRANTED) {
5642 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5643 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5644 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5646 throw new SecurityException(msg);
5649 final long callingId = Binder.clearCallingIdentity();
5651 synchronized (this) {
5652 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5653 final int NP = mProcessNames.getMap().size();
5654 for (int ip = 0; ip < NP; ip++) {
5655 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5656 final int NA = apps.size();
5657 for (int ia = 0; ia < NA; ia++) {
5658 final ProcessRecord app = apps.valueAt(ia);
5661 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5662 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5669 final int N = procs.size();
5670 for (int i = 0; i < N; i++) {
5671 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5675 Binder.restoreCallingIdentity(callingId);
5680 public void forceStopPackage(final String packageName, int userId) {
5681 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5682 != PackageManager.PERMISSION_GRANTED) {
5683 String msg = "Permission Denial: forceStopPackage() from pid="
5684 + Binder.getCallingPid()
5685 + ", uid=" + Binder.getCallingUid()
5686 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5688 throw new SecurityException(msg);
5690 final int callingPid = Binder.getCallingPid();
5691 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5692 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5693 long callingId = Binder.clearCallingIdentity();
5695 IPackageManager pm = AppGlobals.getPackageManager();
5696 synchronized(this) {
5697 int[] users = userId == UserHandle.USER_ALL
5698 ? mUserController.getUsers() : new int[] { userId };
5699 for (int user : users) {
5702 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5704 } catch (RemoteException e) {
5707 Slog.w(TAG, "Invalid packageName: " + packageName);
5711 pm.setPackageStoppedState(packageName, true, user);
5712 } catch (RemoteException e) {
5713 } catch (IllegalArgumentException e) {
5714 Slog.w(TAG, "Failed trying to unstop package "
5715 + packageName + ": " + e);
5717 if (mUserController.isUserRunningLocked(user, 0)) {
5718 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5719 finishForceStopPackageLocked(packageName, pkgUid);
5724 Binder.restoreCallingIdentity(callingId);
5729 public void addPackageDependency(String packageName) {
5730 synchronized (this) {
5731 int callingPid = Binder.getCallingPid();
5732 if (callingPid == Process.myPid()) {
5737 synchronized (mPidsSelfLocked) {
5738 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5741 if (proc.pkgDeps == null) {
5742 proc.pkgDeps = new ArraySet<String>(1);
5744 proc.pkgDeps.add(packageName);
5750 * The pkg name and app id have to be specified.
5753 public void killApplication(String pkg, int appId, int userId, String reason) {
5757 // Make sure the uid is valid.
5759 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5762 int callerUid = Binder.getCallingUid();
5763 // Only the system server can kill an application
5764 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5765 // Post an aysnc message to kill the application
5766 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5769 Bundle bundle = new Bundle();
5770 bundle.putString("pkg", pkg);
5771 bundle.putString("reason", reason);
5773 mHandler.sendMessage(msg);
5775 throw new SecurityException(callerUid + " cannot kill pkg: " +
5781 public void closeSystemDialogs(String reason) {
5782 enforceNotIsolatedCaller("closeSystemDialogs");
5784 final int pid = Binder.getCallingPid();
5785 final int uid = Binder.getCallingUid();
5786 final long origId = Binder.clearCallingIdentity();
5788 synchronized (this) {
5789 // Only allow this from foreground processes, so that background
5790 // applications can't abuse it to prevent system UI from being shown.
5791 if (uid >= Process.FIRST_APPLICATION_UID) {
5793 synchronized (mPidsSelfLocked) {
5794 proc = mPidsSelfLocked.get(pid);
5796 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5797 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5798 + " from background process " + proc);
5802 closeSystemDialogsLocked(reason);
5805 Binder.restoreCallingIdentity(origId);
5809 void closeSystemDialogsLocked(String reason) {
5810 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5811 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5812 | Intent.FLAG_RECEIVER_FOREGROUND);
5813 if (reason != null) {
5814 intent.putExtra("reason", reason);
5816 mWindowManager.closeSystemDialogs(reason);
5818 mStackSupervisor.closeSystemDialogsLocked();
5820 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5821 AppOpsManager.OP_NONE, null, false, false,
5822 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5826 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5827 enforceNotIsolatedCaller("getProcessMemoryInfo");
5828 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5829 for (int i=pids.length-1; i>=0; i--) {
5832 synchronized (this) {
5833 synchronized (mPidsSelfLocked) {
5834 proc = mPidsSelfLocked.get(pids[i]);
5835 oomAdj = proc != null ? proc.setAdj : 0;
5838 infos[i] = new Debug.MemoryInfo();
5839 Debug.getMemoryInfo(pids[i], infos[i]);
5841 synchronized (this) {
5842 if (proc.thread != null && proc.setAdj == oomAdj) {
5843 // Record this for posterity if the process has been stable.
5844 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5845 infos[i].getTotalUss(), false, proc.pkgList);
5854 public long[] getProcessPss(int[] pids) {
5855 enforceNotIsolatedCaller("getProcessPss");
5856 long[] pss = new long[pids.length];
5857 for (int i=pids.length-1; i>=0; i--) {
5860 synchronized (this) {
5861 synchronized (mPidsSelfLocked) {
5862 proc = mPidsSelfLocked.get(pids[i]);
5863 oomAdj = proc != null ? proc.setAdj : 0;
5866 long[] tmpUss = new long[1];
5867 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5869 synchronized (this) {
5870 if (proc.thread != null && proc.setAdj == oomAdj) {
5871 // Record this for posterity if the process has been stable.
5872 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5881 public void killApplicationProcess(String processName, int uid) {
5882 if (processName == null) {
5886 int callerUid = Binder.getCallingUid();
5887 // Only the system server can kill an application
5888 if (callerUid == Process.SYSTEM_UID) {
5889 synchronized (this) {
5890 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5891 if (app != null && app.thread != null) {
5893 app.thread.scheduleSuicide();
5894 } catch (RemoteException e) {
5895 // If the other end already died, then our work here is done.
5898 Slog.w(TAG, "Process/uid not found attempting kill of "
5899 + processName + " / " + uid);
5903 throw new SecurityException(callerUid + " cannot kill app process: " +
5908 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5909 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5910 false, true, false, false, UserHandle.getUserId(uid), reason);
5913 private void finishForceStopPackageLocked(final String packageName, int uid) {
5914 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5915 Uri.fromParts("package", packageName, null));
5916 if (!mProcessesReady) {
5917 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5918 | Intent.FLAG_RECEIVER_FOREGROUND);
5920 intent.putExtra(Intent.EXTRA_UID, uid);
5921 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5922 broadcastIntentLocked(null, null, intent,
5923 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5924 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5928 private final boolean killPackageProcessesLocked(String packageName, int appId,
5929 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5930 boolean doit, boolean evenPersistent, String reason) {
5931 ArrayList<ProcessRecord> procs = new ArrayList<>();
5933 // Remove all processes this package may have touched: all with the
5934 // same UID (except for the system or root user), and all whose name
5935 // matches the package name.
5936 final int NP = mProcessNames.getMap().size();
5937 for (int ip=0; ip<NP; ip++) {
5938 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5939 final int NA = apps.size();
5940 for (int ia=0; ia<NA; ia++) {
5941 ProcessRecord app = apps.valueAt(ia);
5942 if (app.persistent && !evenPersistent) {
5943 // we don't kill persistent processes
5953 // Skip process if it doesn't meet our oom adj requirement.
5954 if (app.setAdj < minOomAdj) {
5958 // If no package is specified, we call all processes under the
5960 if (packageName == null) {
5961 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5964 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5967 // Package has been specified, we want to hit all processes
5968 // that match it. We need to qualify this by the processes
5969 // that are running under the specified app and user ID.
5971 final boolean isDep = app.pkgDeps != null
5972 && app.pkgDeps.contains(packageName);
5973 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5976 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5979 if (!app.pkgList.containsKey(packageName) && !isDep) {
5984 // Process has passed all conditions, kill it!
5993 int N = procs.size();
5994 for (int i=0; i<N; i++) {
5995 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5997 updateOomAdjLocked();
6001 private void cleanupDisabledPackageComponentsLocked(
6002 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6004 Set<String> disabledClasses = null;
6005 boolean packageDisabled = false;
6006 IPackageManager pm = AppGlobals.getPackageManager();
6008 if (changedClasses == null) {
6009 // Nothing changed...
6013 // Determine enable/disable state of the package and its components.
6014 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6015 for (int i = changedClasses.length - 1; i >= 0; i--) {
6016 final String changedClass = changedClasses[i];
6018 if (changedClass.equals(packageName)) {
6020 // Entire package setting changed
6021 enabled = pm.getApplicationEnabledSetting(packageName,
6022 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6023 } catch (Exception e) {
6024 // No such package/component; probably racing with uninstall. In any
6025 // event it means we have nothing further to do here.
6028 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6029 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6030 if (packageDisabled) {
6031 // Entire package is disabled.
6032 // No need to continue to check component states.
6033 disabledClasses = null;
6038 enabled = pm.getComponentEnabledSetting(
6039 new ComponentName(packageName, changedClass),
6040 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6041 } catch (Exception e) {
6042 // As above, probably racing with uninstall.
6045 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6046 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6047 if (disabledClasses == null) {
6048 disabledClasses = new ArraySet<>(changedClasses.length);
6050 disabledClasses.add(changedClass);
6055 if (!packageDisabled && disabledClasses == null) {
6056 // Nothing to do here...
6060 // Clean-up disabled activities.
6061 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6062 packageName, disabledClasses, true, false, userId) && mBooted) {
6063 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6064 mStackSupervisor.scheduleIdleLocked();
6067 // Clean-up disabled tasks
6068 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6070 // Clean-up disabled services.
6071 mServices.bringDownDisabledPackageServicesLocked(
6072 packageName, disabledClasses, userId, false, killProcess, true);
6074 // Clean-up disabled providers.
6075 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6076 mProviderMap.collectPackageProvidersLocked(
6077 packageName, disabledClasses, true, false, userId, providers);
6078 for (int i = providers.size() - 1; i >= 0; i--) {
6079 removeDyingProviderLocked(null, providers.get(i), true);
6082 // Clean-up disabled broadcast receivers.
6083 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6084 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6085 packageName, disabledClasses, userId, true);
6090 final boolean clearBroadcastQueueForUserLocked(int userId) {
6091 boolean didSomething = false;
6092 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6093 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6094 null, null, userId, true);
6096 return didSomething;
6099 final boolean forceStopPackageLocked(String packageName, int appId,
6100 boolean callerWillRestart, boolean purgeCache, boolean doit,
6101 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6104 if (userId == UserHandle.USER_ALL && packageName == null) {
6105 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6108 if (appId < 0 && packageName != null) {
6110 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6111 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6112 } catch (RemoteException e) {
6117 if (packageName != null) {
6118 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6119 + " user=" + userId + ": " + reason);
6121 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6124 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6127 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6128 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6129 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6131 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6132 packageName, null, doit, evenPersistent, userId)) {
6136 didSomething = true;
6139 if (mServices.bringDownDisabledPackageServicesLocked(
6140 packageName, null, userId, evenPersistent, true, doit)) {
6144 didSomething = true;
6147 if (packageName == null) {
6148 // Remove all sticky broadcasts from this user.
6149 mStickyBroadcasts.remove(userId);
6152 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6153 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6154 userId, providers)) {
6158 didSomething = true;
6160 for (i = providers.size() - 1; i >= 0; i--) {
6161 removeDyingProviderLocked(null, providers.get(i), true);
6164 // Remove transient permissions granted from/to this package/user
6165 removeUriPermissionsForPackageLocked(packageName, userId, false);
6168 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6169 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6170 packageName, null, userId, doit);
6174 if (packageName == null || uninstalling) {
6175 // Remove pending intents. For now we only do this when force
6176 // stopping users, because we have some problems when doing this
6177 // for packages -- app widgets are not currently cleaned up for
6178 // such packages, so they can be left with bad pending intents.
6179 if (mIntentSenderRecords.size() > 0) {
6180 Iterator<WeakReference<PendingIntentRecord>> it
6181 = mIntentSenderRecords.values().iterator();
6182 while (it.hasNext()) {
6183 WeakReference<PendingIntentRecord> wpir = it.next();
6188 PendingIntentRecord pir = wpir.get();
6193 if (packageName == null) {
6194 // Stopping user, remove all objects for the user.
6195 if (pir.key.userId != userId) {
6196 // Not the same user, skip it.
6200 if (UserHandle.getAppId(pir.uid) != appId) {
6201 // Different app id, skip it.
6204 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6205 // Different user, skip it.
6208 if (!pir.key.packageName.equals(packageName)) {
6209 // Different package, skip it.
6216 didSomething = true;
6218 pir.canceled = true;
6219 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6220 pir.key.activity.pendingResults.remove(pir.ref);
6227 if (purgeCache && packageName != null) {
6228 AttributeCache ac = AttributeCache.instance();
6230 ac.removePackage(packageName);
6234 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6235 mStackSupervisor.scheduleIdleLocked();
6239 return didSomething;
6242 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6243 ProcessRecord old = mProcessNames.remove(name, uid);
6245 old.uidRecord.numProcs--;
6246 if (old.uidRecord.numProcs == 0) {
6247 // No more processes using this uid, tell clients it is gone.
6248 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6249 "No more processes in " + old.uidRecord);
6250 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6251 mActiveUids.remove(uid);
6252 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6254 old.uidRecord = null;
6256 mIsolatedProcesses.remove(uid);
6260 private final void addProcessNameLocked(ProcessRecord proc) {
6261 // We shouldn't already have a process under this name, but just in case we
6262 // need to clean up whatever may be there now.
6263 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6264 if (old == proc && proc.persistent) {
6265 // We are re-adding a persistent process. Whatevs! Just leave it there.
6266 Slog.w(TAG, "Re-adding persistent process " + proc);
6267 } else if (old != null) {
6268 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6270 UidRecord uidRec = mActiveUids.get(proc.uid);
6271 if (uidRec == null) {
6272 uidRec = new UidRecord(proc.uid);
6273 // This is the first appearance of the uid, report it now!
6274 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6275 "Creating new process uid: " + uidRec);
6276 mActiveUids.put(proc.uid, uidRec);
6277 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6278 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6280 proc.uidRecord = uidRec;
6282 mProcessNames.put(proc.processName, proc.uid, proc);
6283 if (proc.isolated) {
6284 mIsolatedProcesses.put(proc.uid, proc);
6288 boolean removeProcessLocked(ProcessRecord app,
6289 boolean callerWillRestart, boolean allowRestart, String reason) {
6290 final String name = app.processName;
6291 final int uid = app.uid;
6292 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6293 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6295 ProcessRecord old = mProcessNames.get(name, uid);
6297 // This process is no longer active, so nothing to do.
6298 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6301 removeProcessNameLocked(name, uid);
6302 if (mHeavyWeightProcess == app) {
6303 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6304 mHeavyWeightProcess.userId, 0));
6305 mHeavyWeightProcess = null;
6307 boolean needRestart = false;
6308 if (app.pid > 0 && app.pid != MY_PID) {
6310 synchronized (mPidsSelfLocked) {
6311 mPidsSelfLocked.remove(pid);
6312 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6314 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6316 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6318 boolean willRestart = false;
6319 if (app.persistent && !app.isolated) {
6320 if (!callerWillRestart) {
6326 app.kill(reason, true);
6327 handleAppDiedLocked(app, willRestart, allowRestart);
6329 removeLruProcessLocked(app);
6330 addAppLocked(app.info, false, null /* ABI override */);
6333 mRemovedProcesses.add(app);
6339 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6340 cleanupAppInLaunchingProvidersLocked(app, true);
6341 removeProcessLocked(app, false, true, "timeout publishing content providers");
6344 private final void processStartTimedOutLocked(ProcessRecord app) {
6345 final int pid = app.pid;
6346 boolean gone = false;
6347 synchronized (mPidsSelfLocked) {
6348 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6349 if (knownApp != null && knownApp.thread == null) {
6350 mPidsSelfLocked.remove(pid);
6356 Slog.w(TAG, "Process " + app + " failed to attach");
6357 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6358 pid, app.uid, app.processName);
6359 removeProcessNameLocked(app.processName, app.uid);
6360 if (mHeavyWeightProcess == app) {
6361 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6362 mHeavyWeightProcess.userId, 0));
6363 mHeavyWeightProcess = null;
6365 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6367 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6369 // Take care of any launching providers waiting for this process.
6370 cleanupAppInLaunchingProvidersLocked(app, true);
6371 // Take care of any services that are waiting for the process.
6372 mServices.processStartTimedOutLocked(app);
6373 app.kill("start timeout", true);
6374 removeLruProcessLocked(app);
6375 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6376 Slog.w(TAG, "Unattached app died before backup, skipping");
6378 IBackupManager bm = IBackupManager.Stub.asInterface(
6379 ServiceManager.getService(Context.BACKUP_SERVICE));
6380 bm.agentDisconnected(app.info.packageName);
6381 } catch (RemoteException e) {
6382 // Can't happen; the backup manager is local
6385 if (isPendingBroadcastProcessLocked(pid)) {
6386 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6387 skipPendingBroadcastLocked(pid);
6390 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6394 private final boolean attachApplicationLocked(IApplicationThread thread,
6397 // Find the application record that is being attached... either via
6398 // the pid if we are running in multiple processes, or just pull the
6399 // next app record if we are emulating process with anonymous threads.
6401 if (pid != MY_PID && pid >= 0) {
6402 synchronized (mPidsSelfLocked) {
6403 app = mPidsSelfLocked.get(pid);
6410 Slog.w(TAG, "No pending application record for pid " + pid
6411 + " (IApplicationThread " + thread + "); dropping process");
6412 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6413 if (pid > 0 && pid != MY_PID) {
6414 Process.killProcessQuiet(pid);
6415 //TODO: killProcessGroup(app.info.uid, pid);
6418 thread.scheduleExit();
6419 } catch (Exception e) {
6420 // Ignore exceptions.
6426 // If this application record is still attached to a previous
6427 // process, clean it up now.
6428 if (app.thread != null) {
6429 handleAppDiedLocked(app, true, true);
6432 // Tell the process all about itself.
6434 if (DEBUG_ALL) Slog.v(
6435 TAG, "Binding process pid " + pid + " to record " + app);
6437 final String processName = app.processName;
6439 AppDeathRecipient adr = new AppDeathRecipient(
6441 thread.asBinder().linkToDeath(adr, 0);
6442 app.deathRecipient = adr;
6443 } catch (RemoteException e) {
6444 app.resetPackageList(mProcessStats);
6445 startProcessLocked(app, "link fail", processName);
6449 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6451 app.makeActive(thread, mProcessStats);
6452 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6453 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6454 app.forcingToForeground = null;
6455 updateProcessForegroundLocked(app, false, false);
6456 app.hasShownUi = false;
6457 app.debugging = false;
6459 app.killedByAm = false;
6461 // We carefully use the same state that PackageManager uses for
6462 // filtering, since we use this flag to decide if we need to install
6463 // providers when user is unlocked later
6464 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6466 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6468 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6469 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6471 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6472 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6474 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6478 Slog.i(TAG, "Launching preboot mode app: " + app);
6481 if (DEBUG_ALL) Slog.v(
6482 TAG, "New app record " + app
6483 + " thread=" + thread.asBinder() + " pid=" + pid);
6485 int testMode = IApplicationThread.DEBUG_OFF;
6486 if (mDebugApp != null && mDebugApp.equals(processName)) {
6487 testMode = mWaitForDebugger
6488 ? IApplicationThread.DEBUG_WAIT
6489 : IApplicationThread.DEBUG_ON;
6490 app.debugging = true;
6491 if (mDebugTransient) {
6492 mDebugApp = mOrigDebugApp;
6493 mWaitForDebugger = mOrigWaitForDebugger;
6496 String profileFile = app.instrumentationProfileFile;
6497 ParcelFileDescriptor profileFd = null;
6498 int samplingInterval = 0;
6499 boolean profileAutoStop = false;
6500 if (mProfileApp != null && mProfileApp.equals(processName)) {
6502 profileFile = mProfileFile;
6503 profileFd = mProfileFd;
6504 samplingInterval = mSamplingInterval;
6505 profileAutoStop = mAutoStopProfiler;
6507 boolean enableTrackAllocation = false;
6508 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6509 enableTrackAllocation = true;
6510 mTrackAllocationApp = null;
6513 // If the app is being launched for restore or full backup, set it up specially
6514 boolean isRestrictedBackupMode = false;
6515 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6516 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6517 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6518 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6519 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6522 if (app.instrumentationClass != null) {
6523 notifyPackageUse(app.instrumentationClass.getPackageName(),
6524 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6526 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6527 + processName + " with config " + mConfiguration);
6528 ApplicationInfo appInfo = app.instrumentationInfo != null
6529 ? app.instrumentationInfo : app.info;
6530 app.compat = compatibilityInfoForPackageLocked(appInfo);
6531 if (profileFd != null) {
6532 profileFd = profileFd.dup();
6534 ProfilerInfo profilerInfo = profileFile == null ? null
6535 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6536 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6537 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6538 app.instrumentationUiAutomationConnection, testMode,
6539 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6540 isRestrictedBackupMode || !normalMode, app.persistent,
6541 new Configuration(mConfiguration), app.compat,
6542 getCommonServicesLocked(app.isolated),
6543 mCoreSettingsObserver.getCoreSettingsLocked());
6544 updateLruProcessLocked(app, false, null);
6545 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6546 } catch (Exception e) {
6547 // todo: Yikes! What should we do? For now we will try to
6548 // start another process, but that could easily get us in
6549 // an infinite loop of restarting processes...
6550 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6552 app.resetPackageList(mProcessStats);
6553 app.unlinkDeathRecipient();
6554 startProcessLocked(app, "bind fail", processName);
6558 // Remove this record from the list of starting applications.
6559 mPersistentStartingProcesses.remove(app);
6560 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6561 "Attach application locked removing on hold: " + app);
6562 mProcessesOnHold.remove(app);
6564 boolean badApp = false;
6565 boolean didSomething = false;
6567 // See if the top visible activity is waiting to run in this process...
6570 if (mStackSupervisor.attachApplicationLocked(app)) {
6571 didSomething = true;
6573 } catch (Exception e) {
6574 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6579 // Find any services that should be running in this process...
6582 didSomething |= mServices.attachApplicationLocked(app, processName);
6583 } catch (Exception e) {
6584 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6589 // Check if a next-broadcast receiver is in this process...
6590 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6592 didSomething |= sendPendingBroadcastsLocked(app);
6593 } catch (Exception e) {
6594 // If the app died trying to launch the receiver we declare it 'bad'
6595 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6600 // Check whether the next backup agent is in this process...
6601 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6602 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6603 "New app is backup target, launching agent for " + app);
6604 notifyPackageUse(mBackupTarget.appInfo.packageName,
6605 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6607 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6608 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6609 mBackupTarget.backupMode);
6610 } catch (Exception e) {
6611 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6617 app.kill("error during init", true);
6618 handleAppDiedLocked(app, false, true);
6622 if (!didSomething) {
6623 updateOomAdjLocked();
6630 public final void attachApplication(IApplicationThread thread) {
6631 synchronized (this) {
6632 int callingPid = Binder.getCallingPid();
6633 final long origId = Binder.clearCallingIdentity();
6634 attachApplicationLocked(thread, callingPid);
6635 Binder.restoreCallingIdentity(origId);
6640 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6641 final long origId = Binder.clearCallingIdentity();
6642 synchronized (this) {
6643 ActivityStack stack = ActivityRecord.getStackLocked(token);
6644 if (stack != null) {
6646 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6647 if (stopProfiling) {
6648 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6651 } catch (IOException e) {
6653 clearProfilerLocked();
6658 Binder.restoreCallingIdentity(origId);
6661 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6662 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6663 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6666 void enableScreenAfterBoot() {
6667 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6668 SystemClock.uptimeMillis());
6669 mWindowManager.enableScreenAfterBoot();
6671 synchronized (this) {
6672 updateEventDispatchingLocked();
6677 public void showBootMessage(final CharSequence msg, final boolean always) {
6678 if (Binder.getCallingUid() != Process.myUid()) {
6679 // These days only the core system can call this, so apps can't get in
6680 // the way of what we show about running them.
6682 mWindowManager.showBootMessage(msg, always);
6686 public void keyguardWaitingForActivityDrawn() {
6687 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6688 final long token = Binder.clearCallingIdentity();
6690 synchronized (this) {
6691 if (DEBUG_LOCKSCREEN) logLockScreen("");
6692 mWindowManager.keyguardWaitingForActivityDrawn();
6693 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6694 mLockScreenShown = LOCK_SCREEN_LEAVING;
6695 updateSleepIfNeededLocked();
6699 Binder.restoreCallingIdentity(token);
6704 public void keyguardGoingAway(int flags) {
6705 enforceNotIsolatedCaller("keyguardGoingAway");
6706 final long token = Binder.clearCallingIdentity();
6708 synchronized (this) {
6709 if (DEBUG_LOCKSCREEN) logLockScreen("");
6710 mWindowManager.keyguardGoingAway(flags);
6711 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6712 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6713 updateSleepIfNeededLocked();
6715 // Some stack visibility might change (e.g. docked stack)
6716 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6717 applyVrModeIfNeededLocked(mFocusedActivity, true);
6721 Binder.restoreCallingIdentity(token);
6725 final void finishBooting() {
6726 synchronized (this) {
6727 if (!mBootAnimationComplete) {
6728 mCallFinishBooting = true;
6731 mCallFinishBooting = false;
6734 ArraySet<String> completedIsas = new ArraySet<String>();
6735 for (String abi : Build.SUPPORTED_ABIS) {
6736 Process.establishZygoteConnectionForAbi(abi);
6737 final String instructionSet = VMRuntime.getInstructionSet(abi);
6738 if (!completedIsas.contains(instructionSet)) {
6740 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6741 } catch (InstallerException e) {
6742 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6743 e.getMessage() +")");
6745 completedIsas.add(instructionSet);
6749 IntentFilter pkgFilter = new IntentFilter();
6750 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6751 pkgFilter.addDataScheme("package");
6752 mContext.registerReceiver(new BroadcastReceiver() {
6754 public void onReceive(Context context, Intent intent) {
6755 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6757 for (String pkg : pkgs) {
6758 synchronized (ActivityManagerService.this) {
6759 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6760 0, "query restart")) {
6761 setResultCode(Activity.RESULT_OK);
6770 IntentFilter dumpheapFilter = new IntentFilter();
6771 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6772 mContext.registerReceiver(new BroadcastReceiver() {
6774 public void onReceive(Context context, Intent intent) {
6775 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6776 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6778 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6783 // Let system services know.
6784 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6786 synchronized (this) {
6787 // Ensure that any processes we had put on hold are now started
6789 final int NP = mProcessesOnHold.size();
6791 ArrayList<ProcessRecord> procs =
6792 new ArrayList<ProcessRecord>(mProcessesOnHold);
6793 for (int ip=0; ip<NP; ip++) {
6794 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6796 startProcessLocked(procs.get(ip), "on-hold", null);
6800 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6801 // Start looking for apps that are abusing wake locks.
6802 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6803 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6804 // Tell anyone interested that we are done booting!
6805 SystemProperties.set("sys.boot_completed", "1");
6807 // And trigger dev.bootcomplete if we are not showing encryption progress
6808 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6809 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6810 SystemProperties.set("dev.bootcomplete", "1");
6812 mUserController.sendBootCompletedLocked(
6813 new IIntentReceiver.Stub() {
6815 public void performReceive(Intent intent, int resultCode,
6816 String data, Bundle extras, boolean ordered,
6817 boolean sticky, int sendingUser) {
6818 synchronized (ActivityManagerService.this) {
6819 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6824 scheduleStartProfilesLocked();
6830 public void bootAnimationComplete() {
6831 final boolean callFinishBooting;
6832 synchronized (this) {
6833 callFinishBooting = mCallFinishBooting;
6834 mBootAnimationComplete = true;
6836 if (callFinishBooting) {
6837 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6839 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6843 final void ensureBootCompleted() {
6845 boolean enableScreen;
6846 synchronized (this) {
6849 enableScreen = !mBooted;
6854 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6856 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6860 enableScreenAfterBoot();
6865 public final void activityResumed(IBinder token) {
6866 final long origId = Binder.clearCallingIdentity();
6867 synchronized(this) {
6868 ActivityStack stack = ActivityRecord.getStackLocked(token);
6869 if (stack != null) {
6870 stack.activityResumedLocked(token);
6873 Binder.restoreCallingIdentity(origId);
6877 public final void activityPaused(IBinder token) {
6878 final long origId = Binder.clearCallingIdentity();
6879 synchronized(this) {
6880 ActivityStack stack = ActivityRecord.getStackLocked(token);
6881 if (stack != null) {
6882 stack.activityPausedLocked(token, false);
6885 Binder.restoreCallingIdentity(origId);
6889 public final void activityStopped(IBinder token, Bundle icicle,
6890 PersistableBundle persistentState, CharSequence description) {
6891 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6893 // Refuse possible leaked file descriptors
6894 if (icicle != null && icicle.hasFileDescriptors()) {
6895 throw new IllegalArgumentException("File descriptors passed in Bundle");
6898 final long origId = Binder.clearCallingIdentity();
6900 synchronized (this) {
6901 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6903 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6909 Binder.restoreCallingIdentity(origId);
6913 public final void activityDestroyed(IBinder token) {
6914 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6915 synchronized (this) {
6916 ActivityStack stack = ActivityRecord.getStackLocked(token);
6917 if (stack != null) {
6918 stack.activityDestroyedLocked(token, "activityDestroyed");
6924 public final void activityRelaunched(IBinder token) {
6925 final long origId = Binder.clearCallingIdentity();
6926 synchronized (this) {
6927 mStackSupervisor.activityRelaunchedLocked(token);
6929 Binder.restoreCallingIdentity(origId);
6933 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6934 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6935 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6936 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6937 synchronized (this) {
6938 ActivityRecord record = ActivityRecord.isInStackLocked(token);
6939 if (record == null) {
6940 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6941 + "found for: " + token);
6943 record.setSizeConfigurations(horizontalSizeConfiguration,
6944 verticalSizeConfigurations, smallestSizeConfigurations);
6949 public final void backgroundResourcesReleased(IBinder token) {
6950 final long origId = Binder.clearCallingIdentity();
6952 synchronized (this) {
6953 ActivityStack stack = ActivityRecord.getStackLocked(token);
6954 if (stack != null) {
6955 stack.backgroundResourcesReleased();
6959 Binder.restoreCallingIdentity(origId);
6964 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6965 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6969 public final void notifyEnterAnimationComplete(IBinder token) {
6970 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6974 public String getCallingPackage(IBinder token) {
6975 synchronized (this) {
6976 ActivityRecord r = getCallingRecordLocked(token);
6977 return r != null ? r.info.packageName : null;
6982 public ComponentName getCallingActivity(IBinder token) {
6983 synchronized (this) {
6984 ActivityRecord r = getCallingRecordLocked(token);
6985 return r != null ? r.intent.getComponent() : null;
6989 private ActivityRecord getCallingRecordLocked(IBinder token) {
6990 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6998 public ComponentName getActivityClassForToken(IBinder token) {
6999 synchronized(this) {
7000 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7004 return r.intent.getComponent();
7009 public String getPackageForToken(IBinder token) {
7010 synchronized(this) {
7011 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7015 return r.packageName;
7020 public boolean isRootVoiceInteraction(IBinder token) {
7021 synchronized(this) {
7022 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7026 return r.rootVoiceInteraction;
7031 public IIntentSender getIntentSender(int type,
7032 String packageName, IBinder token, String resultWho,
7033 int requestCode, Intent[] intents, String[] resolvedTypes,
7034 int flags, Bundle bOptions, int userId) {
7035 enforceNotIsolatedCaller("getIntentSender");
7036 // Refuse possible leaked file descriptors
7037 if (intents != null) {
7038 if (intents.length < 1) {
7039 throw new IllegalArgumentException("Intents array length must be >= 1");
7041 for (int i=0; i<intents.length; i++) {
7042 Intent intent = intents[i];
7043 if (intent != null) {
7044 if (intent.hasFileDescriptors()) {
7045 throw new IllegalArgumentException("File descriptors passed in Intent");
7047 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7048 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7049 throw new IllegalArgumentException(
7050 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7052 intents[i] = new Intent(intent);
7055 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7056 throw new IllegalArgumentException(
7057 "Intent array length does not match resolvedTypes length");
7060 if (bOptions != null) {
7061 if (bOptions.hasFileDescriptors()) {
7062 throw new IllegalArgumentException("File descriptors passed in options");
7066 synchronized(this) {
7067 int callingUid = Binder.getCallingUid();
7068 int origUserId = userId;
7069 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7070 type == ActivityManager.INTENT_SENDER_BROADCAST,
7071 ALLOW_NON_FULL, "getIntentSender", null);
7072 if (origUserId == UserHandle.USER_CURRENT) {
7073 // We don't want to evaluate this until the pending intent is
7074 // actually executed. However, we do want to always do the
7075 // security checking for it above.
7076 userId = UserHandle.USER_CURRENT;
7079 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7080 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7081 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7082 if (!UserHandle.isSameApp(callingUid, uid)) {
7083 String msg = "Permission Denial: getIntentSender() from pid="
7084 + Binder.getCallingPid()
7085 + ", uid=" + Binder.getCallingUid()
7086 + ", (need uid=" + uid + ")"
7087 + " is not allowed to send as package " + packageName;
7089 throw new SecurityException(msg);
7093 return getIntentSenderLocked(type, packageName, callingUid, userId,
7094 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7096 } catch (RemoteException e) {
7097 throw new SecurityException(e);
7102 IIntentSender getIntentSenderLocked(int type, String packageName,
7103 int callingUid, int userId, IBinder token, String resultWho,
7104 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7106 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7107 ActivityRecord activity = null;
7108 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7109 activity = ActivityRecord.isInStackLocked(token);
7110 if (activity == null) {
7111 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7114 if (activity.finishing) {
7115 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7120 // We're going to be splicing together extras before sending, so we're
7121 // okay poking into any contained extras.
7122 if (intents != null) {
7123 for (int i = 0; i < intents.length; i++) {
7124 intents[i].setDefusable(true);
7127 Bundle.setDefusable(bOptions, true);
7129 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7130 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7131 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7132 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7133 |PendingIntent.FLAG_UPDATE_CURRENT);
7135 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7136 type, packageName, activity, resultWho,
7137 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7138 WeakReference<PendingIntentRecord> ref;
7139 ref = mIntentSenderRecords.get(key);
7140 PendingIntentRecord rec = ref != null ? ref.get() : null;
7142 if (!cancelCurrent) {
7143 if (updateCurrent) {
7144 if (rec.key.requestIntent != null) {
7145 rec.key.requestIntent.replaceExtras(intents != null ?
7146 intents[intents.length - 1] : null);
7148 if (intents != null) {
7149 intents[intents.length-1] = rec.key.requestIntent;
7150 rec.key.allIntents = intents;
7151 rec.key.allResolvedTypes = resolvedTypes;
7153 rec.key.allIntents = null;
7154 rec.key.allResolvedTypes = null;
7159 rec.canceled = true;
7160 mIntentSenderRecords.remove(key);
7165 rec = new PendingIntentRecord(this, key, callingUid);
7166 mIntentSenderRecords.put(key, rec.ref);
7167 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7168 if (activity.pendingResults == null) {
7169 activity.pendingResults
7170 = new HashSet<WeakReference<PendingIntentRecord>>();
7172 activity.pendingResults.add(rec.ref);
7178 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7179 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7180 if (target instanceof PendingIntentRecord) {
7181 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7182 finishedReceiver, requiredPermission, options);
7184 if (intent == null) {
7185 // Weird case: someone has given us their own custom IIntentSender, and now
7186 // they have someone else trying to send to it but of course this isn't
7187 // really a PendingIntent, so there is no base Intent, and the caller isn't
7188 // supplying an Intent... but we never want to dispatch a null Intent to
7189 // a receiver, so um... let's make something up.
7190 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7191 intent = new Intent(Intent.ACTION_MAIN);
7194 target.send(code, intent, resolvedType, null, requiredPermission, options);
7195 } catch (RemoteException e) {
7197 // Platform code can rely on getting a result back when the send is done, but if
7198 // this intent sender is from outside of the system we can't rely on it doing that.
7199 // So instead we don't give it the result receiver, and instead just directly
7200 // report the finish immediately.
7201 if (finishedReceiver != null) {
7203 finishedReceiver.performReceive(intent, 0,
7204 null, null, false, false, UserHandle.getCallingUserId());
7205 } catch (RemoteException e) {
7213 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7215 * <p>{@code callerUid} must be allowed to request such whitelist by calling
7216 * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7218 void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7219 if (DEBUG_WHITELISTS) {
7220 Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7221 + targetUid + ", " + duration + ")");
7223 synchronized (mPidsSelfLocked) {
7224 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7226 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7229 if (!pr.whitelistManager) {
7230 if (DEBUG_WHITELISTS) {
7231 Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7232 + callerPid + " is not allowed");
7238 final long token = Binder.clearCallingIdentity();
7240 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7241 true, "pe from uid:" + callerUid);
7243 Binder.restoreCallingIdentity(token);
7248 public void cancelIntentSender(IIntentSender sender) {
7249 if (!(sender instanceof PendingIntentRecord)) {
7252 synchronized(this) {
7253 PendingIntentRecord rec = (PendingIntentRecord)sender;
7255 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7256 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7257 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7258 String msg = "Permission Denial: cancelIntentSender() from pid="
7259 + Binder.getCallingPid()
7260 + ", uid=" + Binder.getCallingUid()
7261 + " is not allowed to cancel packges "
7262 + rec.key.packageName;
7264 throw new SecurityException(msg);
7266 } catch (RemoteException e) {
7267 throw new SecurityException(e);
7269 cancelIntentSenderLocked(rec, true);
7273 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7274 rec.canceled = true;
7275 mIntentSenderRecords.remove(rec.key);
7276 if (cleanActivity && rec.key.activity != null) {
7277 rec.key.activity.pendingResults.remove(rec.ref);
7282 public String getPackageForIntentSender(IIntentSender pendingResult) {
7283 if (!(pendingResult instanceof PendingIntentRecord)) {
7287 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7288 return res.key.packageName;
7289 } catch (ClassCastException e) {
7295 public int getUidForIntentSender(IIntentSender sender) {
7296 if (sender instanceof PendingIntentRecord) {
7298 PendingIntentRecord res = (PendingIntentRecord)sender;
7300 } catch (ClassCastException e) {
7307 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7308 if (!(pendingResult instanceof PendingIntentRecord)) {
7312 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7313 if (res.key.allIntents == null) {
7316 for (int i=0; i<res.key.allIntents.length; i++) {
7317 Intent intent = res.key.allIntents[i];
7318 if (intent.getPackage() != null && intent.getComponent() != null) {
7323 } catch (ClassCastException e) {
7329 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7330 if (!(pendingResult instanceof PendingIntentRecord)) {
7334 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7335 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7339 } catch (ClassCastException e) {
7345 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7346 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7347 "getIntentForIntentSender()");
7348 if (!(pendingResult instanceof PendingIntentRecord)) {
7352 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7353 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7354 } catch (ClassCastException e) {
7360 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7361 if (!(pendingResult instanceof PendingIntentRecord)) {
7365 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7366 synchronized (this) {
7367 return getTagForIntentSenderLocked(res, prefix);
7369 } catch (ClassCastException e) {
7374 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7375 final Intent intent = res.key.requestIntent;
7376 if (intent != null) {
7377 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7378 || res.lastTagPrefix.equals(prefix))) {
7381 res.lastTagPrefix = prefix;
7382 final StringBuilder sb = new StringBuilder(128);
7383 if (prefix != null) {
7386 if (intent.getAction() != null) {
7387 sb.append(intent.getAction());
7388 } else if (intent.getComponent() != null) {
7389 intent.getComponent().appendShortString(sb);
7393 return res.lastTag = sb.toString();
7399 public void setProcessLimit(int max) {
7400 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7401 "setProcessLimit()");
7402 synchronized (this) {
7403 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7404 mProcessLimitOverride = max;
7410 public int getProcessLimit() {
7411 synchronized (this) {
7412 return mProcessLimitOverride;
7416 void foregroundTokenDied(ForegroundToken token) {
7417 synchronized (ActivityManagerService.this) {
7418 synchronized (mPidsSelfLocked) {
7420 = mForegroundProcesses.get(token.pid);
7424 mForegroundProcesses.remove(token.pid);
7425 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7429 pr.forcingToForeground = null;
7430 updateProcessForegroundLocked(pr, false, false);
7432 updateOomAdjLocked();
7437 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7438 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7439 "setProcessForeground()");
7440 synchronized(this) {
7441 boolean changed = false;
7443 synchronized (mPidsSelfLocked) {
7444 ProcessRecord pr = mPidsSelfLocked.get(pid);
7445 if (pr == null && isForeground) {
7446 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7449 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7450 if (oldToken != null) {
7451 oldToken.token.unlinkToDeath(oldToken, 0);
7452 mForegroundProcesses.remove(pid);
7454 pr.forcingToForeground = null;
7458 if (isForeground && token != null) {
7459 ForegroundToken newToken = new ForegroundToken() {
7461 public void binderDied() {
7462 foregroundTokenDied(this);
7466 newToken.token = token;
7468 token.linkToDeath(newToken, 0);
7469 mForegroundProcesses.put(pid, newToken);
7470 pr.forcingToForeground = token;
7472 } catch (RemoteException e) {
7473 // If the process died while doing this, we will later
7474 // do the cleanup with the process death link.
7480 updateOomAdjLocked();
7486 public boolean isAppForeground(int uid) throws RemoteException {
7487 synchronized (this) {
7488 UidRecord uidRec = mActiveUids.get(uid);
7489 if (uidRec == null || uidRec.idle) {
7492 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7496 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7497 // be guarded by permission checking.
7498 int getUidState(int uid) {
7499 synchronized (this) {
7500 UidRecord uidRec = mActiveUids.get(uid);
7501 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7506 public boolean isInMultiWindowMode(IBinder token) {
7507 final long origId = Binder.clearCallingIdentity();
7509 synchronized(this) {
7510 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7514 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7515 return !r.task.mFullscreen;
7518 Binder.restoreCallingIdentity(origId);
7523 public boolean isInPictureInPictureMode(IBinder token) {
7524 final long origId = Binder.clearCallingIdentity();
7526 synchronized(this) {
7527 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7528 if (stack == null) {
7531 return stack.mStackId == PINNED_STACK_ID;
7534 Binder.restoreCallingIdentity(origId);
7539 public void enterPictureInPictureMode(IBinder token) {
7540 final long origId = Binder.clearCallingIdentity();
7542 synchronized(this) {
7543 if (!mSupportsPictureInPicture) {
7544 throw new IllegalStateException("enterPictureInPictureMode: "
7545 + "Device doesn't support picture-in-picture mode.");
7548 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7551 throw new IllegalStateException("enterPictureInPictureMode: "
7552 + "Can't find activity for token=" + token);
7555 if (!r.supportsPictureInPicture()) {
7556 throw new IllegalArgumentException("enterPictureInPictureMode: "
7557 + "Picture-In-Picture not supported for r=" + r);
7560 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7562 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7563 final Rect bounds = (pinnedStack != null)
7564 ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7566 mStackSupervisor.moveActivityToPinnedStackLocked(
7567 r, "enterPictureInPictureMode", bounds);
7570 Binder.restoreCallingIdentity(origId);
7574 // =========================================================
7576 // =========================================================
7578 static class ProcessInfoService extends IProcessInfoService.Stub {
7579 final ActivityManagerService mActivityManagerService;
7580 ProcessInfoService(ActivityManagerService activityManagerService) {
7581 mActivityManagerService = activityManagerService;
7585 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7586 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7587 /*in*/ pids, /*out*/ states, null);
7591 public void getProcessStatesAndOomScoresFromPids(
7592 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7593 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7594 /*in*/ pids, /*out*/ states, /*out*/ scores);
7599 * For each PID in the given input array, write the current process state
7600 * for that process into the states array, or -1 to indicate that no
7601 * process with the given PID exists. If scores array is provided, write
7602 * the oom score for the process into the scores array, with INVALID_ADJ
7603 * indicating the PID doesn't exist.
7605 public void getProcessStatesAndOomScoresForPIDs(
7606 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7607 if (scores != null) {
7608 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7609 "getProcessStatesAndOomScoresForPIDs()");
7613 throw new NullPointerException("pids");
7614 } else if (states == null) {
7615 throw new NullPointerException("states");
7616 } else if (pids.length != states.length) {
7617 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7618 } else if (scores != null && pids.length != scores.length) {
7619 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7622 synchronized (mPidsSelfLocked) {
7623 for (int i = 0; i < pids.length; i++) {
7624 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7625 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7627 if (scores != null) {
7628 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7634 // =========================================================
7636 // =========================================================
7638 static class PermissionController extends IPermissionController.Stub {
7639 ActivityManagerService mActivityManagerService;
7640 PermissionController(ActivityManagerService activityManagerService) {
7641 mActivityManagerService = activityManagerService;
7645 public boolean checkPermission(String permission, int pid, int uid) {
7646 return mActivityManagerService.checkPermission(permission, pid,
7647 uid) == PackageManager.PERMISSION_GRANTED;
7651 public String[] getPackagesForUid(int uid) {
7652 return mActivityManagerService.mContext.getPackageManager()
7653 .getPackagesForUid(uid);
7657 public boolean isRuntimePermission(String permission) {
7659 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7660 .getPermissionInfo(permission, 0);
7661 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7662 } catch (NameNotFoundException nnfe) {
7663 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7669 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7671 public int checkComponentPermission(String permission, int pid, int uid,
7672 int owningUid, boolean exported) {
7673 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7674 owningUid, exported);
7678 public Object getAMSLock() {
7679 return ActivityManagerService.this;
7684 * This can be called with or without the global lock held.
7686 int checkComponentPermission(String permission, int pid, int uid,
7687 int owningUid, boolean exported) {
7688 if (pid == MY_PID) {
7689 return PackageManager.PERMISSION_GRANTED;
7691 return ActivityManager.checkComponentPermission(permission, uid,
7692 owningUid, exported);
7696 * As the only public entry point for permissions checking, this method
7697 * can enforce the semantic that requesting a check on a null global
7698 * permission is automatically denied. (Internally a null permission
7699 * string is used when calling {@link #checkComponentPermission} in cases
7700 * when only uid-based security is needed.)
7702 * This can be called with or without the global lock held.
7705 public int checkPermission(String permission, int pid, int uid) {
7706 if (permission == null) {
7707 return PackageManager.PERMISSION_DENIED;
7709 return checkComponentPermission(permission, pid, uid, -1, true);
7713 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7714 if (permission == null) {
7715 return PackageManager.PERMISSION_DENIED;
7718 // We might be performing an operation on behalf of an indirect binder
7719 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7720 // client identity accordingly before proceeding.
7721 Identity tlsIdentity = sCallerIdentity.get();
7722 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7723 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7724 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7725 uid = tlsIdentity.uid;
7726 pid = tlsIdentity.pid;
7729 return checkComponentPermission(permission, pid, uid, -1, true);
7733 * Binder IPC calls go through the public entry point.
7734 * This can be called with or without the global lock held.
7736 int checkCallingPermission(String permission) {
7737 return checkPermission(permission,
7738 Binder.getCallingPid(),
7739 UserHandle.getAppId(Binder.getCallingUid()));
7743 * This can be called with or without the global lock held.
7745 void enforceCallingPermission(String permission, String func) {
7746 if (checkCallingPermission(permission)
7747 == PackageManager.PERMISSION_GRANTED) {
7751 String msg = "Permission Denial: " + func + " from pid="
7752 + Binder.getCallingPid()
7753 + ", uid=" + Binder.getCallingUid()
7754 + " requires " + permission;
7756 throw new SecurityException(msg);
7760 * Determine if UID is holding permissions required to access {@link Uri} in
7761 * the given {@link ProviderInfo}. Final permission checking is always done
7762 * in {@link ContentProvider}.
7764 private final boolean checkHoldingPermissionsLocked(
7765 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7766 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7767 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7768 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7769 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7770 != PERMISSION_GRANTED) {
7774 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7777 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7778 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7779 if (pi.applicationInfo.uid == uid) {
7781 } else if (!pi.exported) {
7785 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7786 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7788 // check if target holds top-level <provider> permissions
7789 if (!readMet && pi.readPermission != null && considerUidPermissions
7790 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7793 if (!writeMet && pi.writePermission != null && considerUidPermissions
7794 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7798 // track if unprotected read/write is allowed; any denied
7799 // <path-permission> below removes this ability
7800 boolean allowDefaultRead = pi.readPermission == null;
7801 boolean allowDefaultWrite = pi.writePermission == null;
7803 // check if target holds any <path-permission> that match uri
7804 final PathPermission[] pps = pi.pathPermissions;
7806 final String path = grantUri.uri.getPath();
7808 while (i > 0 && (!readMet || !writeMet)) {
7810 PathPermission pp = pps[i];
7811 if (pp.match(path)) {
7813 final String pprperm = pp.getReadPermission();
7814 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7815 "Checking read perm for " + pprperm + " for " + pp.getPath()
7816 + ": match=" + pp.match(path)
7817 + " check=" + pm.checkUidPermission(pprperm, uid));
7818 if (pprperm != null) {
7819 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7820 == PERMISSION_GRANTED) {
7823 allowDefaultRead = false;
7828 final String ppwperm = pp.getWritePermission();
7829 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7830 "Checking write perm " + ppwperm + " for " + pp.getPath()
7831 + ": match=" + pp.match(path)
7832 + " check=" + pm.checkUidPermission(ppwperm, uid));
7833 if (ppwperm != null) {
7834 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7835 == PERMISSION_GRANTED) {
7838 allowDefaultWrite = false;
7846 // grant unprotected <provider> read/write, if not blocked by
7847 // <path-permission> above
7848 if (allowDefaultRead) readMet = true;
7849 if (allowDefaultWrite) writeMet = true;
7851 } catch (RemoteException e) {
7855 return readMet && writeMet;
7858 public int getAppStartMode(int uid, String packageName) {
7859 synchronized (this) {
7860 return checkAllowBackgroundLocked(uid, packageName, -1, true);
7864 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7865 boolean allowWhenForeground) {
7866 UidRecord uidRec = mActiveUids.get(uid);
7867 if (!mLenientBackgroundCheck) {
7868 if (!allowWhenForeground || uidRec == null
7869 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7870 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7871 packageName) != AppOpsManager.MODE_ALLOWED) {
7872 return ActivityManager.APP_START_MODE_DELAYED;
7876 } else if (uidRec == null || uidRec.idle) {
7877 if (callingPid >= 0) {
7879 synchronized (mPidsSelfLocked) {
7880 proc = mPidsSelfLocked.get(callingPid);
7882 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7883 // Whoever is instigating this is in the foreground, so we will allow it
7885 return ActivityManager.APP_START_MODE_NORMAL;
7888 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7889 != AppOpsManager.MODE_ALLOWED) {
7890 return ActivityManager.APP_START_MODE_DELAYED;
7893 return ActivityManager.APP_START_MODE_NORMAL;
7896 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7897 ProviderInfo pi = null;
7898 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7903 pi = AppGlobals.getPackageManager().resolveContentProvider(
7904 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7906 } catch (RemoteException ex) {
7912 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7913 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7914 if (targetUris != null) {
7915 return targetUris.get(grantUri);
7920 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7921 String targetPkg, int targetUid, GrantUri grantUri) {
7922 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7923 if (targetUris == null) {
7924 targetUris = Maps.newArrayMap();
7925 mGrantedUriPermissions.put(targetUid, targetUris);
7928 UriPermission perm = targetUris.get(grantUri);
7930 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7931 targetUris.put(grantUri, perm);
7937 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7938 final int modeFlags) {
7939 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7940 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7941 : UriPermission.STRENGTH_OWNED;
7943 // Root gets to do everything.
7948 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7949 if (perms == null) return false;
7951 // First look for exact match
7952 final UriPermission exactPerm = perms.get(grantUri);
7953 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7957 // No exact match, look for prefixes
7958 final int N = perms.size();
7959 for (int i = 0; i < N; i++) {
7960 final UriPermission perm = perms.valueAt(i);
7961 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7962 && perm.getStrength(modeFlags) >= minStrength) {
7971 * @param uri This uri must NOT contain an embedded userId.
7972 * @param userId The userId in which the uri is to be resolved.
7975 public int checkUriPermission(Uri uri, int pid, int uid,
7976 final int modeFlags, int userId, IBinder callerToken) {
7977 enforceNotIsolatedCaller("checkUriPermission");
7979 // Another redirected-binder-call permissions check as in
7980 // {@link checkPermissionWithToken}.
7981 Identity tlsIdentity = sCallerIdentity.get();
7982 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7983 uid = tlsIdentity.uid;
7984 pid = tlsIdentity.pid;
7987 // Our own process gets to do everything.
7988 if (pid == MY_PID) {
7989 return PackageManager.PERMISSION_GRANTED;
7991 synchronized (this) {
7992 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7993 ? PackageManager.PERMISSION_GRANTED
7994 : PackageManager.PERMISSION_DENIED;
7999 * Check if the targetPkg can be granted permission to access uri by
8000 * the callingUid using the given modeFlags. Throws a security exception
8001 * if callingUid is not allowed to do this. Returns the uid of the target
8002 * if the URI permission grant should be performed; returns -1 if it is not
8003 * needed (for example targetPkg already has permission to access the URI).
8004 * If you already know the uid of the target, you can supply it in
8005 * lastTargetUid else set that to -1.
8007 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8008 final int modeFlags, int lastTargetUid) {
8009 if (!Intent.isAccessUriMode(modeFlags)) {
8013 if (targetPkg != null) {
8014 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8015 "Checking grant " + targetPkg + " permission to " + grantUri);
8018 final IPackageManager pm = AppGlobals.getPackageManager();
8020 // If this is not a content: uri, we can't do anything with it.
8021 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8022 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8023 "Can't grant URI permission for non-content URI: " + grantUri);
8027 final String authority = grantUri.uri.getAuthority();
8028 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8029 MATCH_DEBUG_TRIAGED_MISSING);
8031 Slog.w(TAG, "No content provider found for permission check: " +
8032 grantUri.uri.toSafeString());
8036 int targetUid = lastTargetUid;
8037 if (targetUid < 0 && targetPkg != null) {
8039 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8040 UserHandle.getUserId(callingUid));
8041 if (targetUid < 0) {
8042 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8043 "Can't grant URI permission no uid for: " + targetPkg);
8046 } catch (RemoteException ex) {
8051 if (targetUid >= 0) {
8052 // First... does the target actually need this permission?
8053 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8054 // No need to grant the target this permission.
8055 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8056 "Target " + targetPkg + " already has full permission to " + grantUri);
8060 // First... there is no target package, so can anyone access it?
8061 boolean allowed = pi.exported;
8062 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8063 if (pi.readPermission != null) {
8067 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8068 if (pi.writePermission != null) {
8077 /* There is a special cross user grant if:
8078 * - The target is on another user.
8079 * - Apps on the current user can access the uri without any uid permissions.
8080 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8081 * grant uri permissions.
8083 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8084 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8085 modeFlags, false /*without considering the uid permissions*/);
8087 // Second... is the provider allowing granting of URI permissions?
8088 if (!specialCrossUserGrant) {
8089 if (!pi.grantUriPermissions) {
8090 throw new SecurityException("Provider " + pi.packageName
8092 + " does not allow granting of Uri permissions (uri "
8095 if (pi.uriPermissionPatterns != null) {
8096 final int N = pi.uriPermissionPatterns.length;
8097 boolean allowed = false;
8098 for (int i=0; i<N; i++) {
8099 if (pi.uriPermissionPatterns[i] != null
8100 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8106 throw new SecurityException("Provider " + pi.packageName
8108 + " does not allow granting of permission to path of Uri "
8114 // Third... does the caller itself have permission to access
8116 final int callingAppId = UserHandle.getAppId(callingUid);
8117 if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8118 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8119 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8122 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8123 // Require they hold a strong enough Uri permission
8124 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8125 throw new SecurityException("Uid " + callingUid
8126 + " does not have permission to uri " + grantUri);
8134 * @param uri This uri must NOT contain an embedded userId.
8135 * @param userId The userId in which the uri is to be resolved.
8138 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8139 final int modeFlags, int userId) {
8140 enforceNotIsolatedCaller("checkGrantUriPermission");
8141 synchronized(this) {
8142 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8143 new GrantUri(userId, uri, false), modeFlags, -1);
8147 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8148 final int modeFlags, UriPermissionOwner owner) {
8149 if (!Intent.isAccessUriMode(modeFlags)) {
8153 // So here we are: the caller has the assumed permission
8154 // to the uri, and the target doesn't. Let's now give this to
8157 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8158 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8160 final String authority = grantUri.uri.getAuthority();
8161 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8162 MATCH_DEBUG_TRIAGED_MISSING);
8164 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8168 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8169 grantUri.prefix = true;
8171 final UriPermission perm = findOrCreateUriPermissionLocked(
8172 pi.packageName, targetPkg, targetUid, grantUri);
8173 perm.grantModes(modeFlags, owner);
8176 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8177 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8178 if (targetPkg == null) {
8179 throw new NullPointerException("targetPkg");
8182 final IPackageManager pm = AppGlobals.getPackageManager();
8184 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8185 } catch (RemoteException ex) {
8189 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8191 if (targetUid < 0) {
8195 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8199 static class NeededUriGrants extends ArrayList<GrantUri> {
8200 final String targetPkg;
8201 final int targetUid;
8204 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8205 this.targetPkg = targetPkg;
8206 this.targetUid = targetUid;
8212 * Like checkGrantUriPermissionLocked, but takes an Intent.
8214 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8215 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8216 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8217 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8218 + " clip=" + (intent != null ? intent.getClipData() : null)
8219 + " from " + intent + "; flags=0x"
8220 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8222 if (targetPkg == null) {
8223 throw new NullPointerException("targetPkg");
8226 if (intent == null) {
8229 Uri data = intent.getData();
8230 ClipData clip = intent.getClipData();
8231 if (data == null && clip == null) {
8234 // Default userId for uris in the intent (if they don't specify it themselves)
8235 int contentUserHint = intent.getContentUserHint();
8236 if (contentUserHint == UserHandle.USER_CURRENT) {
8237 contentUserHint = UserHandle.getUserId(callingUid);
8239 final IPackageManager pm = AppGlobals.getPackageManager();
8241 if (needed != null) {
8242 targetUid = needed.targetUid;
8245 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8247 } catch (RemoteException ex) {
8250 if (targetUid < 0) {
8251 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8252 "Can't grant URI permission no uid for: " + targetPkg
8253 + " on user " + targetUserId);
8258 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8259 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8261 if (targetUid > 0) {
8262 if (needed == null) {
8263 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8265 needed.add(grantUri);
8269 for (int i=0; i<clip.getItemCount(); i++) {
8270 Uri uri = clip.getItemAt(i).getUri();
8272 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8273 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8275 if (targetUid > 0) {
8276 if (needed == null) {
8277 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8279 needed.add(grantUri);
8282 Intent clipIntent = clip.getItemAt(i).getIntent();
8283 if (clipIntent != null) {
8284 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8285 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8286 if (newNeeded != null) {
8298 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8300 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8301 UriPermissionOwner owner) {
8302 if (needed != null) {
8303 for (int i=0; i<needed.size(); i++) {
8304 GrantUri grantUri = needed.get(i);
8305 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8306 grantUri, needed.flags, owner);
8311 void grantUriPermissionFromIntentLocked(int callingUid,
8312 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8313 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8314 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8315 if (needed == null) {
8319 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8323 * @param uri This uri must NOT contain an embedded userId.
8324 * @param userId The userId in which the uri is to be resolved.
8327 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8328 final int modeFlags, int userId) {
8329 enforceNotIsolatedCaller("grantUriPermission");
8330 GrantUri grantUri = new GrantUri(userId, uri, false);
8331 synchronized(this) {
8332 final ProcessRecord r = getRecordForAppLocked(caller);
8334 throw new SecurityException("Unable to find app for caller "
8336 + " when granting permission to uri " + grantUri);
8338 if (targetPkg == null) {
8339 throw new IllegalArgumentException("null target");
8341 if (grantUri == null) {
8342 throw new IllegalArgumentException("null uri");
8345 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8346 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8347 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8348 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8350 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8351 UserHandle.getUserId(r.uid));
8355 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8356 if (perm.modeFlags == 0) {
8357 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8359 if (perms != null) {
8360 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8361 "Removing " + perm.targetUid + " permission to " + perm.uri);
8363 perms.remove(perm.uri);
8364 if (perms.isEmpty()) {
8365 mGrantedUriPermissions.remove(perm.targetUid);
8371 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8372 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8373 "Revoking all granted permissions to " + grantUri);
8375 final IPackageManager pm = AppGlobals.getPackageManager();
8376 final String authority = grantUri.uri.getAuthority();
8377 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8378 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8380 Slog.w(TAG, "No content provider found for permission revoke: "
8381 + grantUri.toSafeString());
8385 // Does the caller have this permission on the URI?
8386 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8387 // If they don't have direct access to the URI, then revoke any
8388 // ownerless URI permissions that have been granted to them.
8389 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8390 if (perms != null) {
8391 boolean persistChanged = false;
8392 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8393 final UriPermission perm = it.next();
8394 if (perm.uri.sourceUserId == grantUri.sourceUserId
8395 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8396 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8397 "Revoking non-owned " + perm.targetUid
8398 + " permission to " + perm.uri);
8399 persistChanged |= perm.revokeModes(
8400 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8401 if (perm.modeFlags == 0) {
8406 if (perms.isEmpty()) {
8407 mGrantedUriPermissions.remove(callingUid);
8409 if (persistChanged) {
8410 schedulePersistUriGrants();
8416 boolean persistChanged = false;
8418 // Go through all of the permissions and remove any that match.
8419 int N = mGrantedUriPermissions.size();
8420 for (int i = 0; i < N; i++) {
8421 final int targetUid = mGrantedUriPermissions.keyAt(i);
8422 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8424 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8425 final UriPermission perm = it.next();
8426 if (perm.uri.sourceUserId == grantUri.sourceUserId
8427 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8428 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8429 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8430 persistChanged |= perm.revokeModes(
8431 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8432 if (perm.modeFlags == 0) {
8438 if (perms.isEmpty()) {
8439 mGrantedUriPermissions.remove(targetUid);
8445 if (persistChanged) {
8446 schedulePersistUriGrants();
8451 * @param uri This uri must NOT contain an embedded userId.
8452 * @param userId The userId in which the uri is to be resolved.
8455 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8457 enforceNotIsolatedCaller("revokeUriPermission");
8458 synchronized(this) {
8459 final ProcessRecord r = getRecordForAppLocked(caller);
8461 throw new SecurityException("Unable to find app for caller "
8463 + " when revoking permission to uri " + uri);
8466 Slog.w(TAG, "revokeUriPermission: null uri");
8470 if (!Intent.isAccessUriMode(modeFlags)) {
8474 final String authority = uri.getAuthority();
8475 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8476 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8478 Slog.w(TAG, "No content provider found for permission revoke: "
8479 + uri.toSafeString());
8483 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8488 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8491 * @param packageName Package name to match, or {@code null} to apply to all
8493 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8495 * @param persistable If persistable grants should be removed.
8497 private void removeUriPermissionsForPackageLocked(
8498 String packageName, int userHandle, boolean persistable) {
8499 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8500 throw new IllegalArgumentException("Must narrow by either package or user");
8503 boolean persistChanged = false;
8505 int N = mGrantedUriPermissions.size();
8506 for (int i = 0; i < N; i++) {
8507 final int targetUid = mGrantedUriPermissions.keyAt(i);
8508 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8510 // Only inspect grants matching user
8511 if (userHandle == UserHandle.USER_ALL
8512 || userHandle == UserHandle.getUserId(targetUid)) {
8513 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8514 final UriPermission perm = it.next();
8516 // Only inspect grants matching package
8517 if (packageName == null || perm.sourcePkg.equals(packageName)
8518 || perm.targetPkg.equals(packageName)) {
8519 // Hacky solution as part of fixing a security bug; ignore
8520 // grants associated with DownloadManager so we don't have
8521 // to immediately launch it to regrant the permissions
8522 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8523 && !persistable) continue;
8525 persistChanged |= perm.revokeModes(persistable
8526 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8528 // Only remove when no modes remain; any persisted grants
8529 // will keep this alive.
8530 if (perm.modeFlags == 0) {
8536 if (perms.isEmpty()) {
8537 mGrantedUriPermissions.remove(targetUid);
8544 if (persistChanged) {
8545 schedulePersistUriGrants();
8550 public IBinder newUriPermissionOwner(String name) {
8551 enforceNotIsolatedCaller("newUriPermissionOwner");
8552 synchronized(this) {
8553 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8554 return owner.getExternalTokenLocked();
8559 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8560 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8561 synchronized(this) {
8562 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8564 throw new IllegalArgumentException("Activity does not exist; token="
8567 return r.getUriPermissionsLocked().getExternalTokenLocked();
8571 * @param uri This uri must NOT contain an embedded userId.
8572 * @param sourceUserId The userId in which the uri is to be resolved.
8573 * @param targetUserId The userId of the app that receives the grant.
8576 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8577 final int modeFlags, int sourceUserId, int targetUserId) {
8578 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8579 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8580 "grantUriPermissionFromOwner", null);
8581 synchronized(this) {
8582 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8583 if (owner == null) {
8584 throw new IllegalArgumentException("Unknown owner: " + token);
8586 if (fromUid != Binder.getCallingUid()) {
8587 if (Binder.getCallingUid() != Process.myUid()) {
8588 // Only system code can grant URI permissions on behalf
8590 throw new SecurityException("nice try");
8593 if (targetPkg == null) {
8594 throw new IllegalArgumentException("null target");
8597 throw new IllegalArgumentException("null uri");
8600 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8601 modeFlags, owner, targetUserId);
8606 * @param uri This uri must NOT contain an embedded userId.
8607 * @param userId The userId in which the uri is to be resolved.
8610 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8611 synchronized(this) {
8612 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8613 if (owner == null) {
8614 throw new IllegalArgumentException("Unknown owner: " + token);
8618 owner.removeUriPermissionsLocked(mode);
8620 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8625 private void schedulePersistUriGrants() {
8626 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8627 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8628 10 * DateUtils.SECOND_IN_MILLIS);
8632 private void writeGrantedUriPermissions() {
8633 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8635 // Snapshot permissions so we can persist without lock
8636 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8637 synchronized (this) {
8638 final int size = mGrantedUriPermissions.size();
8639 for (int i = 0; i < size; i++) {
8640 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8641 for (UriPermission perm : perms.values()) {
8642 if (perm.persistedModeFlags != 0) {
8643 persist.add(perm.snapshot());
8649 FileOutputStream fos = null;
8651 fos = mGrantFile.startWrite();
8653 XmlSerializer out = new FastXmlSerializer();
8654 out.setOutput(fos, StandardCharsets.UTF_8.name());
8655 out.startDocument(null, true);
8656 out.startTag(null, TAG_URI_GRANTS);
8657 for (UriPermission.Snapshot perm : persist) {
8658 out.startTag(null, TAG_URI_GRANT);
8659 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8660 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8661 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8662 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8663 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8664 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8665 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8666 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8667 out.endTag(null, TAG_URI_GRANT);
8669 out.endTag(null, TAG_URI_GRANTS);
8672 mGrantFile.finishWrite(fos);
8673 } catch (IOException e) {
8675 mGrantFile.failWrite(fos);
8680 private void readGrantedUriPermissionsLocked() {
8681 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8683 final long now = System.currentTimeMillis();
8685 FileInputStream fis = null;
8687 fis = mGrantFile.openRead();
8688 final XmlPullParser in = Xml.newPullParser();
8689 in.setInput(fis, StandardCharsets.UTF_8.name());
8692 while ((type = in.next()) != END_DOCUMENT) {
8693 final String tag = in.getName();
8694 if (type == START_TAG) {
8695 if (TAG_URI_GRANT.equals(tag)) {
8696 final int sourceUserId;
8697 final int targetUserId;
8698 final int userHandle = readIntAttribute(in,
8699 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8700 if (userHandle != UserHandle.USER_NULL) {
8701 // For backwards compatibility.
8702 sourceUserId = userHandle;
8703 targetUserId = userHandle;
8705 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8706 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8708 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8709 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8710 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8711 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8712 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8713 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8715 // Sanity check that provider still belongs to source package
8716 // Both direct boot aware and unaware packages are fine as we
8717 // will do filtering at query time to avoid multiple parsing.
8718 final ProviderInfo pi = getProviderInfoLocked(
8719 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8720 | MATCH_DIRECT_BOOT_UNAWARE);
8721 if (pi != null && sourcePkg.equals(pi.packageName)) {
8724 targetUid = AppGlobals.getPackageManager().getPackageUid(
8725 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8726 } catch (RemoteException e) {
8728 if (targetUid != -1) {
8729 final UriPermission perm = findOrCreateUriPermissionLocked(
8730 sourcePkg, targetPkg, targetUid,
8731 new GrantUri(sourceUserId, uri, prefix));
8732 perm.initPersistedModes(modeFlags, createdTime);
8735 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8736 + " but instead found " + pi);
8741 } catch (FileNotFoundException e) {
8742 // Missing grants is okay
8743 } catch (IOException e) {
8744 Slog.wtf(TAG, "Failed reading Uri grants", e);
8745 } catch (XmlPullParserException e) {
8746 Slog.wtf(TAG, "Failed reading Uri grants", e);
8748 IoUtils.closeQuietly(fis);
8753 * @param uri This uri must NOT contain an embedded userId.
8754 * @param userId The userId in which the uri is to be resolved.
8757 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8758 enforceNotIsolatedCaller("takePersistableUriPermission");
8760 Preconditions.checkFlagsArgument(modeFlags,
8761 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8763 synchronized (this) {
8764 final int callingUid = Binder.getCallingUid();
8765 boolean persistChanged = false;
8766 GrantUri grantUri = new GrantUri(userId, uri, false);
8768 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8769 new GrantUri(userId, uri, false));
8770 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8771 new GrantUri(userId, uri, true));
8773 final boolean exactValid = (exactPerm != null)
8774 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8775 final boolean prefixValid = (prefixPerm != null)
8776 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8778 if (!(exactValid || prefixValid)) {
8779 throw new SecurityException("No persistable permission grants found for UID "
8780 + callingUid + " and Uri " + grantUri.toSafeString());
8784 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8787 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8790 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8792 if (persistChanged) {
8793 schedulePersistUriGrants();
8799 * @param uri This uri must NOT contain an embedded userId.
8800 * @param userId The userId in which the uri is to be resolved.
8803 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8804 enforceNotIsolatedCaller("releasePersistableUriPermission");
8806 Preconditions.checkFlagsArgument(modeFlags,
8807 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8809 synchronized (this) {
8810 final int callingUid = Binder.getCallingUid();
8811 boolean persistChanged = false;
8813 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8814 new GrantUri(userId, uri, false));
8815 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8816 new GrantUri(userId, uri, true));
8817 if (exactPerm == null && prefixPerm == null) {
8818 throw new SecurityException("No permission grants found for UID " + callingUid
8819 + " and Uri " + uri.toSafeString());
8822 if (exactPerm != null) {
8823 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8824 removeUriPermissionIfNeededLocked(exactPerm);
8826 if (prefixPerm != null) {
8827 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8828 removeUriPermissionIfNeededLocked(prefixPerm);
8831 if (persistChanged) {
8832 schedulePersistUriGrants();
8838 * Prune any older {@link UriPermission} for the given UID until outstanding
8839 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8841 * @return if any mutations occured that require persisting.
8843 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8844 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8845 if (perms == null) return false;
8846 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8848 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8849 for (UriPermission perm : perms.values()) {
8850 if (perm.persistedModeFlags != 0) {
8851 persisted.add(perm);
8855 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8856 if (trimCount <= 0) return false;
8858 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8859 for (int i = 0; i < trimCount; i++) {
8860 final UriPermission perm = persisted.get(i);
8862 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8863 "Trimming grant created at " + perm.persistedCreateTime);
8865 perm.releasePersistableModes(~0);
8866 removeUriPermissionIfNeededLocked(perm);
8873 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8874 String packageName, boolean incoming) {
8875 enforceNotIsolatedCaller("getPersistedUriPermissions");
8876 Preconditions.checkNotNull(packageName, "packageName");
8878 final int callingUid = Binder.getCallingUid();
8879 final int callingUserId = UserHandle.getUserId(callingUid);
8880 final IPackageManager pm = AppGlobals.getPackageManager();
8882 final int packageUid = pm.getPackageUid(packageName,
8883 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8884 if (packageUid != callingUid) {
8885 throw new SecurityException(
8886 "Package " + packageName + " does not belong to calling UID " + callingUid);
8888 } catch (RemoteException e) {
8889 throw new SecurityException("Failed to verify package name ownership");
8892 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8893 synchronized (this) {
8895 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8897 if (perms == null) {
8898 Slog.w(TAG, "No permission grants found for " + packageName);
8900 for (UriPermission perm : perms.values()) {
8901 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8902 result.add(perm.buildPersistedPublicApiObject());
8907 final int size = mGrantedUriPermissions.size();
8908 for (int i = 0; i < size; i++) {
8909 final ArrayMap<GrantUri, UriPermission> perms =
8910 mGrantedUriPermissions.valueAt(i);
8911 for (UriPermission perm : perms.values()) {
8912 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8913 result.add(perm.buildPersistedPublicApiObject());
8919 return new ParceledListSlice<android.content.UriPermission>(result);
8923 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8924 String packageName, int userId) {
8925 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8926 "getGrantedUriPermissions");
8928 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8929 synchronized (this) {
8930 final int size = mGrantedUriPermissions.size();
8931 for (int i = 0; i < size; i++) {
8932 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8933 for (UriPermission perm : perms.values()) {
8934 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8935 && perm.persistedModeFlags != 0) {
8936 result.add(perm.buildPersistedPublicApiObject());
8941 return new ParceledListSlice<android.content.UriPermission>(result);
8945 public void clearGrantedUriPermissions(String packageName, int userId) {
8946 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8947 "clearGrantedUriPermissions");
8948 removeUriPermissionsForPackageLocked(packageName, userId, true);
8952 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8953 synchronized (this) {
8955 who != null ? getRecordForAppLocked(who) : null;
8956 if (app == null) return;
8958 Message msg = Message.obtain();
8959 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8961 msg.arg1 = waiting ? 1 : 0;
8962 mUiHandler.sendMessage(msg);
8967 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8968 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8969 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8970 outInfo.availMem = Process.getFreeMemory();
8971 outInfo.totalMem = Process.getTotalMemory();
8972 outInfo.threshold = homeAppMem;
8973 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8974 outInfo.hiddenAppThreshold = cachedAppMem;
8975 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8976 ProcessList.SERVICE_ADJ);
8977 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8978 ProcessList.VISIBLE_APP_ADJ);
8979 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8980 ProcessList.FOREGROUND_APP_ADJ);
8983 // =========================================================
8985 // =========================================================
8988 public List<IAppTask> getAppTasks(String callingPackage) {
8989 int callingUid = Binder.getCallingUid();
8990 long ident = Binder.clearCallingIdentity();
8992 synchronized(this) {
8993 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8995 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8997 final int N = mRecentTasks.size();
8998 for (int i = 0; i < N; i++) {
8999 TaskRecord tr = mRecentTasks.get(i);
9000 // Skip tasks that do not match the caller. We don't need to verify
9001 // callingPackage, because we are also limiting to callingUid and know
9002 // that will limit to the correct security sandbox.
9003 if (tr.effectiveUid != callingUid) {
9006 Intent intent = tr.getBaseIntent();
9007 if (intent == null ||
9008 !callingPackage.equals(intent.getComponent().getPackageName())) {
9011 ActivityManager.RecentTaskInfo taskInfo =
9012 createRecentTaskInfoFromTaskRecord(tr);
9013 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9017 Binder.restoreCallingIdentity(ident);
9024 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9025 final int callingUid = Binder.getCallingUid();
9026 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9028 synchronized(this) {
9029 if (DEBUG_ALL) Slog.v(
9030 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9032 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9035 // TODO: Improve with MRU list from all ActivityStacks.
9036 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9043 * Creates a new RecentTaskInfo from a TaskRecord.
9045 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9046 // Update the task description to reflect any changes in the task stack
9047 tr.updateTaskDescription();
9049 // Compose the recent task info
9050 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9051 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9052 rti.persistentId = tr.taskId;
9053 rti.baseIntent = new Intent(tr.getBaseIntent());
9054 rti.origActivity = tr.origActivity;
9055 rti.realActivity = tr.realActivity;
9056 rti.description = tr.lastDescription;
9057 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9058 rti.userId = tr.userId;
9059 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9060 rti.firstActiveTime = tr.firstActiveTime;
9061 rti.lastActiveTime = tr.lastActiveTime;
9062 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9063 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9064 rti.numActivities = 0;
9065 if (tr.mBounds != null) {
9066 rti.bounds = new Rect(tr.mBounds);
9068 rti.isDockable = tr.canGoInDockedStack();
9069 rti.resizeMode = tr.mResizeMode;
9071 ActivityRecord base = null;
9072 ActivityRecord top = null;
9075 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9076 tmp = tr.mActivities.get(i);
9077 if (tmp.finishing) {
9081 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9084 rti.numActivities++;
9087 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9088 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9093 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9094 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9095 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9097 if (checkPermission(android.Manifest.permission.GET_TASKS,
9098 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9099 // Temporary compatibility: some existing apps on the system image may
9100 // still be requesting the old permission and not switched to the new
9101 // one; if so, we'll still allow them full access. This means we need
9102 // to see if they are holding the old permission and are a system app.
9104 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9106 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9107 + " is using old GET_TASKS but privileged; allowing");
9109 } catch (RemoteException e) {
9114 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9115 + " does not hold REAL_GET_TASKS; limiting output");
9121 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9123 final int callingUid = Binder.getCallingUid();
9124 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9125 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9127 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9128 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9129 synchronized (this) {
9130 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9132 final boolean detailed = checkCallingPermission(
9133 android.Manifest.permission.GET_DETAILED_TASKS)
9134 == PackageManager.PERMISSION_GRANTED;
9136 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9137 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9138 return ParceledListSlice.emptyList();
9140 mRecentTasks.loadUserRecentsLocked(userId);
9142 final int recentsCount = mRecentTasks.size();
9143 ArrayList<ActivityManager.RecentTaskInfo> res =
9144 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9146 final Set<Integer> includedUsers;
9147 if (includeProfiles) {
9148 includedUsers = mUserController.getProfileIds(userId);
9150 includedUsers = new HashSet<>();
9152 includedUsers.add(Integer.valueOf(userId));
9154 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9155 TaskRecord tr = mRecentTasks.get(i);
9156 // Only add calling user or related users recent tasks
9157 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9158 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9162 if (tr.realActivitySuspended) {
9163 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9167 // Return the entry if desired by the caller. We always return
9168 // the first entry, because callers always expect this to be the
9169 // foreground app. We may filter others if the caller has
9170 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9171 // we should exclude the entry.
9175 || (tr.intent == null)
9176 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9179 // If the caller doesn't have the GET_TASKS permission, then only
9180 // allow them to see a small subset of tasks -- their own and home.
9181 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9182 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9186 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9187 if (tr.stack != null && tr.stack.isHomeStack()) {
9188 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9189 "Skipping, home stack task: " + tr);
9193 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9194 final ActivityStack stack = tr.stack;
9195 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9196 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9197 "Skipping, top task in docked stack: " + tr);
9201 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9202 if (tr.stack != null && tr.stack.isPinnedStack()) {
9203 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9204 "Skipping, pinned stack task: " + tr);
9208 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9209 // Don't include auto remove tasks that are finished or finishing.
9210 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9211 "Skipping, auto-remove without activity: " + tr);
9214 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9215 && !tr.isAvailable) {
9216 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9217 "Skipping, unavail real act: " + tr);
9221 if (!tr.mUserSetupComplete) {
9222 // Don't include task launched while user is not done setting-up.
9223 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9224 "Skipping, user setup not complete: " + tr);
9228 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9230 rti.baseIntent.replaceExtras((Bundle)null);
9237 return new ParceledListSlice<>(res);
9242 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9243 synchronized (this) {
9244 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9245 "getTaskThumbnail()");
9246 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9247 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9249 return tr.getTaskThumbnailLocked();
9256 public int addAppTask(IBinder activityToken, Intent intent,
9257 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9258 final int callingUid = Binder.getCallingUid();
9259 final long callingIdent = Binder.clearCallingIdentity();
9262 synchronized (this) {
9263 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9265 throw new IllegalArgumentException("Activity does not exist; token="
9268 ComponentName comp = intent.getComponent();
9270 throw new IllegalArgumentException("Intent " + intent
9271 + " must specify explicit component");
9273 if (thumbnail.getWidth() != mThumbnailWidth
9274 || thumbnail.getHeight() != mThumbnailHeight) {
9275 throw new IllegalArgumentException("Bad thumbnail size: got "
9276 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9277 + mThumbnailWidth + "x" + mThumbnailHeight);
9279 if (intent.getSelector() != null) {
9280 intent.setSelector(null);
9282 if (intent.getSourceBounds() != null) {
9283 intent.setSourceBounds(null);
9285 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9286 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9287 // The caller has added this as an auto-remove task... that makes no
9288 // sense, so turn off auto-remove.
9289 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9291 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9292 // Must be a new task.
9293 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9295 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9296 mLastAddedTaskActivity = null;
9298 ActivityInfo ainfo = mLastAddedTaskActivity;
9299 if (ainfo == null) {
9300 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9301 comp, 0, UserHandle.getUserId(callingUid));
9302 if (ainfo.applicationInfo.uid != callingUid) {
9303 throw new SecurityException(
9304 "Can't add task for another application: target uid="
9305 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9309 // Use the full screen as the context for the task thumbnail
9310 final Point displaySize = new Point();
9311 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9312 r.task.stack.getDisplaySize(displaySize);
9313 thumbnailInfo.taskWidth = displaySize.x;
9314 thumbnailInfo.taskHeight = displaySize.y;
9315 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9317 TaskRecord task = new TaskRecord(this,
9318 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9319 ainfo, intent, description, thumbnailInfo);
9321 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9323 // If this would have caused a trim, then we'll abort because that
9324 // means it would be added at the end of the list but then just removed.
9325 return INVALID_TASK_ID;
9328 final int N = mRecentTasks.size();
9329 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9330 final TaskRecord tr = mRecentTasks.remove(N - 1);
9331 tr.removedFromRecents();
9334 task.inRecents = true;
9335 mRecentTasks.add(task);
9336 r.task.stack.addTask(task, false, "addAppTask");
9338 task.setLastThumbnailLocked(thumbnail);
9339 task.freeLastThumbnail();
9344 Binder.restoreCallingIdentity(callingIdent);
9349 public Point getAppTaskThumbnailSize() {
9350 synchronized (this) {
9351 return new Point(mThumbnailWidth, mThumbnailHeight);
9356 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9357 synchronized (this) {
9358 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9360 r.setTaskDescription(td);
9361 r.task.updateTaskDescription();
9367 public void setTaskResizeable(int taskId, int resizeableMode) {
9368 synchronized (this) {
9369 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9370 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9372 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9375 if (task.mResizeMode != resizeableMode) {
9376 task.mResizeMode = resizeableMode;
9377 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9378 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9379 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9385 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9386 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9387 long ident = Binder.clearCallingIdentity();
9389 synchronized (this) {
9390 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9392 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9395 int stackId = task.stack.mStackId;
9396 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9397 // in crop windows resize mode or if the task size is affected by the docked stack
9398 // changing size. No need to update configuration.
9399 if (bounds != null && task.inCropWindowsResizeMode()
9400 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9401 mWindowManager.scrollTask(task.taskId, bounds);
9405 // Place the task in the right stack if it isn't there already based on
9406 // the requested bounds.
9407 // The stack transition logic is:
9408 // - a null bounds on a freeform task moves that task to fullscreen
9409 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9410 // that task to freeform
9411 // - otherwise the task is not moved
9412 if (!StackId.isTaskResizeAllowed(stackId)) {
9413 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9415 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9416 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9417 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9418 stackId = FREEFORM_WORKSPACE_STACK_ID;
9420 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9421 if (stackId != task.stack.mStackId) {
9422 mStackSupervisor.moveTaskToStackUncheckedLocked(
9423 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9424 preserveWindow = false;
9427 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9428 false /* deferResume */);
9431 Binder.restoreCallingIdentity(ident);
9436 public Rect getTaskBounds(int taskId) {
9437 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9438 long ident = Binder.clearCallingIdentity();
9439 Rect rect = new Rect();
9441 synchronized (this) {
9442 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9443 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9445 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9448 if (task.stack != null) {
9449 // Return the bounds from window manager since it will be adjusted for various
9450 // things like the presense of a docked stack for tasks that aren't resizeable.
9451 mWindowManager.getTaskBounds(task.taskId, rect);
9453 // Task isn't in window manager yet since it isn't associated with a stack.
9454 // Return the persist value from activity manager
9455 if (task.mBounds != null) {
9456 rect.set(task.mBounds);
9457 } else if (task.mLastNonFullscreenBounds != null) {
9458 rect.set(task.mLastNonFullscreenBounds);
9463 Binder.restoreCallingIdentity(ident);
9469 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9470 if (userId != UserHandle.getCallingUserId()) {
9471 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9472 "getTaskDescriptionIcon");
9474 final File passedIconFile = new File(filePath);
9475 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9476 passedIconFile.getName());
9477 if (!legitIconFile.getPath().equals(filePath)
9478 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9479 throw new IllegalArgumentException("Bad file path: " + filePath
9480 + " passed for userId " + userId);
9482 return mRecentTasks.getTaskDescriptionIcon(filePath);
9486 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9487 throws RemoteException {
9488 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9489 opts.getCustomInPlaceResId() == 0) {
9490 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9491 "with valid animation");
9493 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9494 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9495 opts.getCustomInPlaceResId());
9496 mWindowManager.executeAppTransition();
9499 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9500 boolean removeFromRecents) {
9501 if (removeFromRecents) {
9502 mRecentTasks.remove(tr);
9503 tr.removedFromRecents();
9505 ComponentName component = tr.getBaseIntent().getComponent();
9506 if (component == null) {
9507 Slog.w(TAG, "No component for base intent of task: " + tr);
9511 // Find any running services associated with this app and stop if needed.
9512 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9518 // Determine if the process(es) for this task should be killed.
9519 final String pkg = component.getPackageName();
9520 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9521 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9522 for (int i = 0; i < pmap.size(); i++) {
9524 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9525 for (int j = 0; j < uids.size(); j++) {
9526 ProcessRecord proc = uids.valueAt(j);
9527 if (proc.userId != tr.userId) {
9528 // Don't kill process for a different user.
9531 if (proc == mHomeProcess) {
9532 // Don't kill the home process along with tasks from the same package.
9535 if (!proc.pkgList.containsKey(pkg)) {
9536 // Don't kill process that is not associated with this task.
9540 for (int k = 0; k < proc.activities.size(); k++) {
9541 TaskRecord otherTask = proc.activities.get(k).task;
9542 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9543 // Don't kill process(es) that has an activity in a different task that is
9549 if (proc.foregroundServices) {
9550 // Don't kill process(es) with foreground service.
9554 // Add process to kill list.
9555 procsToKill.add(proc);
9559 // Kill the running processes.
9560 for (int i = 0; i < procsToKill.size(); i++) {
9561 ProcessRecord pr = procsToKill.get(i);
9562 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9563 && pr.curReceiver == null) {
9564 pr.kill("remove task", true);
9566 // We delay killing processes that are not in the background or running a receiver.
9567 pr.waitingToKill = "remove task";
9572 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9573 // Remove all tasks with activities in the specified package from the list of recent tasks
9574 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9575 TaskRecord tr = mRecentTasks.get(i);
9576 if (tr.userId != userId) continue;
9578 ComponentName cn = tr.intent.getComponent();
9579 if (cn != null && cn.getPackageName().equals(packageName)) {
9580 // If the package name matches, remove the task.
9581 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9586 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9589 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9590 TaskRecord tr = mRecentTasks.get(i);
9591 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9595 ComponentName cn = tr.intent.getComponent();
9596 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9597 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9598 if (sameComponent) {
9599 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9605 * Removes the task with the specified task id.
9607 * @param taskId Identifier of the task to be removed.
9608 * @param killProcess Kill any process associated with the task if possible.
9609 * @param removeFromRecents Whether to also remove the task from recents.
9610 * @return Returns true if the given task was found and removed.
9612 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9613 boolean removeFromRecents) {
9614 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9615 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9617 tr.removeTaskActivitiesLocked();
9618 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9619 if (tr.isPersistable) {
9620 notifyTaskPersisterLocked(null, true);
9624 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9629 public void removeStack(int stackId) {
9630 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9631 if (stackId == HOME_STACK_ID) {
9632 throw new IllegalArgumentException("Removing home stack is not allowed.");
9635 synchronized (this) {
9636 final long ident = Binder.clearCallingIdentity();
9638 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9639 if (stack == null) {
9642 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9643 for (int i = tasks.size() - 1; i >= 0; i--) {
9644 removeTaskByIdLocked(
9645 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9648 Binder.restoreCallingIdentity(ident);
9654 public boolean removeTask(int taskId) {
9655 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9656 synchronized (this) {
9657 final long ident = Binder.clearCallingIdentity();
9659 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9661 Binder.restoreCallingIdentity(ident);
9667 * TODO: Add mController hook
9670 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9671 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9673 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9674 synchronized(this) {
9675 moveTaskToFrontLocked(taskId, flags, bOptions);
9679 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9680 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9682 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9683 Binder.getCallingUid(), -1, -1, "Task to front")) {
9684 ActivityOptions.abort(options);
9687 final long origId = Binder.clearCallingIdentity();
9689 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9691 Slog.d(TAG, "Could not find task for id: "+ taskId);
9694 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9695 mStackSupervisor.showLockTaskToast();
9696 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9699 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9700 if (prev != null && prev.isRecentsActivity()) {
9701 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9703 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9704 false /* forceNonResizable */);
9706 Binder.restoreCallingIdentity(origId);
9708 ActivityOptions.abort(options);
9712 * Moves an activity, and all of the other activities within the same task, to the bottom
9713 * of the history stack. The activity's order within the task is unchanged.
9715 * @param token A reference to the activity we wish to move
9716 * @param nonRoot If false then this only works if the activity is the root
9717 * of a task; if true it will work for any activity in a task.
9718 * @return Returns true if the move completed, false if not.
9721 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9722 enforceNotIsolatedCaller("moveActivityTaskToBack");
9723 synchronized(this) {
9724 final long origId = Binder.clearCallingIdentity();
9726 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9727 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9729 if (mStackSupervisor.isLockedTask(task)) {
9730 mStackSupervisor.showLockTaskToast();
9733 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9736 Binder.restoreCallingIdentity(origId);
9743 public void moveTaskBackwards(int task) {
9744 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9745 "moveTaskBackwards()");
9747 synchronized(this) {
9748 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9749 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9752 final long origId = Binder.clearCallingIdentity();
9753 moveTaskBackwardsLocked(task);
9754 Binder.restoreCallingIdentity(origId);
9758 private final void moveTaskBackwardsLocked(int task) {
9759 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9763 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9764 IActivityContainerCallback callback) throws RemoteException {
9765 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9766 synchronized (this) {
9767 if (parentActivityToken == null) {
9768 throw new IllegalArgumentException("parent token must not be null");
9770 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9774 if (callback == null) {
9775 throw new IllegalArgumentException("callback must not be null");
9777 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9782 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9783 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9784 synchronized (this) {
9785 mStackSupervisor.deleteActivityContainer(container);
9790 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9791 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9792 synchronized (this) {
9793 final int stackId = mStackSupervisor.getNextStackId();
9794 final ActivityStack stack =
9795 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9796 if (stack == null) {
9799 return stack.mActivityContainer;
9804 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9805 synchronized (this) {
9806 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9807 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9808 return stack.mActivityContainer.getDisplayId();
9810 return Display.DEFAULT_DISPLAY;
9815 public int getActivityStackId(IBinder token) throws RemoteException {
9816 synchronized (this) {
9817 ActivityStack stack = ActivityRecord.getStackLocked(token);
9818 if (stack == null) {
9819 return INVALID_STACK_ID;
9821 return stack.mStackId;
9826 public void exitFreeformMode(IBinder token) throws RemoteException {
9827 synchronized (this) {
9828 long ident = Binder.clearCallingIdentity();
9830 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9832 throw new IllegalArgumentException(
9833 "exitFreeformMode: No activity record matching token=" + token);
9835 final ActivityStack stack = r.getStackLocked(token);
9836 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9837 throw new IllegalStateException(
9838 "exitFreeformMode: You can only go fullscreen from freeform.");
9840 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9841 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9842 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9844 Binder.restoreCallingIdentity(ident);
9850 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9851 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9852 if (stackId == HOME_STACK_ID) {
9853 throw new IllegalArgumentException(
9854 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9856 synchronized (this) {
9857 long ident = Binder.clearCallingIdentity();
9859 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9860 + " to stackId=" + stackId + " toTop=" + toTop);
9861 if (stackId == DOCKED_STACK_ID) {
9862 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9863 null /* initialBounds */);
9865 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9866 !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9867 if (result && stackId == DOCKED_STACK_ID) {
9868 // If task moved to docked stack - show recents if needed.
9869 mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9870 "moveTaskToDockedStack");
9873 Binder.restoreCallingIdentity(ident);
9879 public void swapDockedAndFullscreenStack() throws RemoteException {
9880 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9881 synchronized (this) {
9882 long ident = Binder.clearCallingIdentity();
9884 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9885 FULLSCREEN_WORKSPACE_STACK_ID);
9886 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9888 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9889 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9891 if (topTask == null || tasks == null || tasks.size() == 0) {
9893 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9897 // TODO: App transition
9898 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9900 // Defer the resume so resume/pausing while moving stacks is dangerous.
9901 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9902 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9903 ANIMATE, true /* deferResume */);
9904 final int size = tasks.size();
9905 for (int i = 0; i < size; i++) {
9906 final int id = tasks.get(i).taskId;
9907 if (id == topTask.taskId) {
9910 mStackSupervisor.moveTaskToStackLocked(id,
9911 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9912 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9915 // Because we deferred the resume, to avoid conflicts with stack switches while
9916 // resuming, we need to do it after all the tasks are moved.
9917 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9918 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9920 mWindowManager.executeAppTransition();
9922 Binder.restoreCallingIdentity(ident);
9928 * Moves the input task to the docked stack.
9930 * @param taskId Id of task to move.
9931 * @param createMode The mode the docked stack should be created in if it doesn't exist
9933 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9935 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9936 * @param toTop If the task and stack should be moved to the top.
9937 * @param animate Whether we should play an animation for the moving the task
9938 * @param initialBounds If the docked stack gets created, it will use these bounds for the
9939 * docked stack. Pass {@code null} to use default bounds.
9942 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9943 Rect initialBounds, boolean moveHomeStackFront) {
9944 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9945 synchronized (this) {
9946 long ident = Binder.clearCallingIdentity();
9948 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9949 + " to createMode=" + createMode + " toTop=" + toTop);
9950 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9951 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9952 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9953 animate, DEFER_RESUME);
9955 if (moveHomeStackFront) {
9956 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9958 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9962 Binder.restoreCallingIdentity(ident);
9968 * Moves the top activity in the input stackId to the pinned stack.
9970 * @param stackId Id of stack to move the top activity to pinned stack.
9971 * @param bounds Bounds to use for pinned stack.
9973 * @return True if the top activity of the input stack was successfully moved to the pinned
9977 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9978 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9979 synchronized (this) {
9980 if (!mSupportsPictureInPicture) {
9981 throw new IllegalStateException("moveTopActivityToPinnedStack:"
9982 + "Device doesn't support picture-in-pciture mode");
9985 long ident = Binder.clearCallingIdentity();
9987 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9989 Binder.restoreCallingIdentity(ident);
9995 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9996 boolean preserveWindows, boolean animate, int animationDuration) {
9997 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9998 long ident = Binder.clearCallingIdentity();
10000 synchronized (this) {
10002 if (stackId == PINNED_STACK_ID) {
10003 mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10005 throw new IllegalArgumentException("Stack: " + stackId
10006 + " doesn't support animated resize.");
10009 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10010 null /* tempTaskInsetBounds */, preserveWindows,
10011 allowResizeInDockedMode, !DEFER_RESUME);
10015 Binder.restoreCallingIdentity(ident);
10020 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10021 Rect tempDockedTaskInsetBounds,
10022 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10023 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10024 "resizeDockedStack()");
10025 long ident = Binder.clearCallingIdentity();
10027 synchronized (this) {
10028 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10029 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10033 Binder.restoreCallingIdentity(ident);
10038 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10039 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10040 "resizePinnedStack()");
10041 final long ident = Binder.clearCallingIdentity();
10043 synchronized (this) {
10044 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10047 Binder.restoreCallingIdentity(ident);
10052 public void positionTaskInStack(int taskId, int stackId, int position) {
10053 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10054 if (stackId == HOME_STACK_ID) {
10055 throw new IllegalArgumentException(
10056 "positionTaskInStack: Attempt to change the position of task "
10057 + taskId + " in/to home stack");
10059 synchronized (this) {
10060 long ident = Binder.clearCallingIdentity();
10062 if (DEBUG_STACK) Slog.d(TAG_STACK,
10063 "positionTaskInStack: positioning task=" + taskId
10064 + " in stackId=" + stackId + " at position=" + position);
10065 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10067 Binder.restoreCallingIdentity(ident);
10073 public List<StackInfo> getAllStackInfos() {
10074 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10075 long ident = Binder.clearCallingIdentity();
10077 synchronized (this) {
10078 return mStackSupervisor.getAllStackInfosLocked();
10081 Binder.restoreCallingIdentity(ident);
10086 public StackInfo getStackInfo(int stackId) {
10087 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10088 long ident = Binder.clearCallingIdentity();
10090 synchronized (this) {
10091 return mStackSupervisor.getStackInfoLocked(stackId);
10094 Binder.restoreCallingIdentity(ident);
10099 public boolean isInHomeStack(int taskId) {
10100 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10101 long ident = Binder.clearCallingIdentity();
10103 synchronized (this) {
10104 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10105 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10106 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10109 Binder.restoreCallingIdentity(ident);
10114 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10115 synchronized(this) {
10116 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10121 public void updateDeviceOwner(String packageName) {
10122 final int callingUid = Binder.getCallingUid();
10123 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10124 throw new SecurityException("updateDeviceOwner called from non-system process");
10126 synchronized (this) {
10127 mDeviceOwnerName = packageName;
10132 public void updateLockTaskPackages(int userId, String[] packages) {
10133 final int callingUid = Binder.getCallingUid();
10134 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10135 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10136 "updateLockTaskPackages()");
10138 synchronized (this) {
10139 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10140 Arrays.toString(packages));
10141 mLockTaskPackages.put(userId, packages);
10142 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10147 void startLockTaskModeLocked(TaskRecord task) {
10148 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10149 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10153 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10154 // is initiated by system after the pinning request was shown and locked mode is initiated
10155 // by an authorized app directly
10156 final int callingUid = Binder.getCallingUid();
10157 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10158 long ident = Binder.clearCallingIdentity();
10160 if (!isSystemInitiated) {
10161 task.mLockTaskUid = callingUid;
10162 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10163 // startLockTask() called by app and task mode is lockTaskModeDefault.
10164 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10165 StatusBarManagerInternal statusBarManager =
10166 LocalServices.getService(StatusBarManagerInternal.class);
10167 if (statusBarManager != null) {
10168 statusBarManager.showScreenPinningRequest(task.taskId);
10173 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10174 if (stack == null || task != stack.topTask()) {
10175 throw new IllegalArgumentException("Invalid task, not in foreground");
10178 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10180 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10181 ActivityManager.LOCK_TASK_MODE_PINNED :
10182 ActivityManager.LOCK_TASK_MODE_LOCKED,
10183 "startLockTask", true);
10185 Binder.restoreCallingIdentity(ident);
10190 public void startLockTaskMode(int taskId) {
10191 synchronized (this) {
10192 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10193 if (task != null) {
10194 startLockTaskModeLocked(task);
10200 public void startLockTaskMode(IBinder token) {
10201 synchronized (this) {
10202 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10206 final TaskRecord task = r.task;
10207 if (task != null) {
10208 startLockTaskModeLocked(task);
10214 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10215 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10216 // This makes inner call to look as if it was initiated by system.
10217 long ident = Binder.clearCallingIdentity();
10219 synchronized (this) {
10220 startLockTaskMode(taskId);
10223 Binder.restoreCallingIdentity(ident);
10228 public void stopLockTaskMode() {
10229 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10230 if (lockTask == null) {
10231 // Our work here is done.
10235 final int callingUid = Binder.getCallingUid();
10236 final int lockTaskUid = lockTask.mLockTaskUid;
10237 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10238 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10242 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10243 // It is possible lockTaskMode was started by the system process because
10244 // android:lockTaskMode is set to a locking value in the application manifest
10245 // instead of the app calling startLockTaskMode. In this case
10246 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10247 // {@link TaskRecord.effectiveUid} instead. Also caller with
10248 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10249 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10250 && callingUid != lockTaskUid
10251 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10252 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10253 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10256 long ident = Binder.clearCallingIdentity();
10258 Log.d(TAG, "stopLockTaskMode");
10260 synchronized (this) {
10261 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10262 "stopLockTask", true);
10264 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10266 tm.showInCallScreen(false);
10269 Binder.restoreCallingIdentity(ident);
10274 * This API should be called by SystemUI only when user perform certain action to dismiss
10275 * lock task mode. We should only dismiss pinned lock task mode in this case.
10278 public void stopSystemLockTaskMode() throws RemoteException {
10279 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10280 stopLockTaskMode();
10282 mStackSupervisor.showLockTaskToast();
10287 public boolean isInLockTaskMode() {
10288 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10292 public int getLockTaskModeState() {
10293 synchronized (this) {
10294 return mStackSupervisor.getLockTaskModeState();
10299 public void showLockTaskEscapeMessage(IBinder token) {
10300 synchronized (this) {
10301 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10305 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10309 // =========================================================
10310 // CONTENT PROVIDERS
10311 // =========================================================
10313 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10314 List<ProviderInfo> providers = null;
10316 providers = AppGlobals.getPackageManager()
10317 .queryContentProviders(app.processName, app.uid,
10318 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10319 | MATCH_DEBUG_TRIAGED_MISSING)
10321 } catch (RemoteException ex) {
10323 if (DEBUG_MU) Slog.v(TAG_MU,
10324 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10325 int userId = app.userId;
10326 if (providers != null) {
10327 int N = providers.size();
10328 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10329 for (int i=0; i<N; i++) {
10330 // TODO: keep logic in sync with installEncryptionUnawareProviders
10332 (ProviderInfo)providers.get(i);
10333 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10334 cpi.name, cpi.flags);
10335 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10336 // This is a singleton provider, but a user besides the
10337 // default user is asking to initialize a process it runs
10338 // in... well, no, it doesn't actually run in this process,
10339 // it runs in the process of the default user. Get rid of it.
10340 providers.remove(i);
10346 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10347 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10349 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10350 mProviderMap.putProviderByClass(comp, cpr);
10352 if (DEBUG_MU) Slog.v(TAG_MU,
10353 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10354 app.pubProviders.put(cpi.name, cpr);
10355 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10356 // Don't add this if it is a platform component that is marked
10357 // to run in multiple processes, because this is actually
10358 // part of the framework so doesn't make sense to track as a
10359 // separate apk in the process.
10360 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10363 notifyPackageUse(cpi.applicationInfo.packageName,
10364 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10371 * Check if the calling UID has a possible chance at accessing the provider
10372 * at the given authority and user.
10374 public String checkContentProviderAccess(String authority, int userId) {
10375 if (userId == UserHandle.USER_ALL) {
10376 mContext.enforceCallingOrSelfPermission(
10377 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10378 userId = UserHandle.getCallingUserId();
10381 ProviderInfo cpi = null;
10383 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10384 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10385 | PackageManager.MATCH_DIRECT_BOOT_AWARE
10386 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10388 } catch (RemoteException ignored) {
10391 // TODO: make this an outright failure in a future platform release;
10392 // until then anonymous content notifications are unprotected
10393 //return "Failed to find provider " + authority + " for user " + userId;
10397 ProcessRecord r = null;
10398 synchronized (mPidsSelfLocked) {
10399 r = mPidsSelfLocked.get(Binder.getCallingPid());
10402 return "Failed to find PID " + Binder.getCallingPid();
10405 synchronized (this) {
10406 return checkContentProviderPermissionLocked(cpi, r, userId, true);
10411 * Check if {@link ProcessRecord} has a possible chance at accessing the
10412 * given {@link ProviderInfo}. Final permission checking is always done
10413 * in {@link ContentProvider}.
10415 private final String checkContentProviderPermissionLocked(
10416 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10417 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10418 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10419 boolean checkedGrants = false;
10421 // Looking for cross-user grants before enforcing the typical cross-users permissions
10422 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10423 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10424 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10427 checkedGrants = true;
10429 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10430 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10431 if (userId != tmpTargetUserId) {
10432 // When we actually went to determine the final targer user ID, this ended
10433 // up different than our initial check for the authority. This is because
10434 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10435 // SELF. So we need to re-check the grants again.
10436 checkedGrants = false;
10439 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10440 cpi.applicationInfo.uid, cpi.exported)
10441 == PackageManager.PERMISSION_GRANTED) {
10444 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10445 cpi.applicationInfo.uid, cpi.exported)
10446 == PackageManager.PERMISSION_GRANTED) {
10450 PathPermission[] pps = cpi.pathPermissions;
10452 int i = pps.length;
10455 PathPermission pp = pps[i];
10456 String pprperm = pp.getReadPermission();
10457 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10458 cpi.applicationInfo.uid, cpi.exported)
10459 == PackageManager.PERMISSION_GRANTED) {
10462 String ppwperm = pp.getWritePermission();
10463 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10464 cpi.applicationInfo.uid, cpi.exported)
10465 == PackageManager.PERMISSION_GRANTED) {
10470 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10475 if (!cpi.exported) {
10476 msg = "Permission Denial: opening provider " + cpi.name
10477 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10478 + ", uid=" + callingUid + ") that is not exported from uid "
10479 + cpi.applicationInfo.uid;
10481 msg = "Permission Denial: opening provider " + cpi.name
10482 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10483 + ", uid=" + callingUid + ") requires "
10484 + cpi.readPermission + " or " + cpi.writePermission;
10491 * Returns if the ContentProvider has granted a uri to callingUid
10493 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10494 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10495 if (perms != null) {
10496 for (int i=perms.size()-1; i>=0; i--) {
10497 GrantUri grantUri = perms.keyAt(i);
10498 if (grantUri.sourceUserId == userId || !checkUser) {
10499 if (matchesProvider(grantUri.uri, cpi)) {
10509 * Returns true if the uri authority is one of the authorities specified in the provider.
10511 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10512 String uriAuth = uri.getAuthority();
10513 String cpiAuth = cpi.authority;
10514 if (cpiAuth.indexOf(';') == -1) {
10515 return cpiAuth.equals(uriAuth);
10517 String[] cpiAuths = cpiAuth.split(";");
10518 int length = cpiAuths.length;
10519 for (int i = 0; i < length; i++) {
10520 if (cpiAuths[i].equals(uriAuth)) return true;
10525 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10526 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10528 for (int i=0; i<r.conProviders.size(); i++) {
10529 ContentProviderConnection conn = r.conProviders.get(i);
10530 if (conn.provider == cpr) {
10531 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10532 "Adding provider requested by "
10533 + r.processName + " from process "
10534 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10535 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10537 conn.stableCount++;
10538 conn.numStableIncs++;
10540 conn.unstableCount++;
10541 conn.numUnstableIncs++;
10546 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10548 conn.stableCount = 1;
10549 conn.numStableIncs = 1;
10551 conn.unstableCount = 1;
10552 conn.numUnstableIncs = 1;
10554 cpr.connections.add(conn);
10555 r.conProviders.add(conn);
10556 startAssociationLocked(r.uid, r.processName, r.curProcState,
10557 cpr.uid, cpr.name, cpr.info.processName);
10560 cpr.addExternalProcessHandleLocked(externalProcessToken);
10564 boolean decProviderCountLocked(ContentProviderConnection conn,
10565 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10566 if (conn != null) {
10567 cpr = conn.provider;
10568 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10569 "Removing provider requested by "
10570 + conn.client.processName + " from process "
10571 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10572 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10574 conn.stableCount--;
10576 conn.unstableCount--;
10578 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10579 cpr.connections.remove(conn);
10580 conn.client.conProviders.remove(conn);
10581 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10582 // The client is more important than last activity -- note the time this
10583 // is happening, so we keep the old provider process around a bit as last
10584 // activity to avoid thrashing it.
10585 if (cpr.proc != null) {
10586 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10589 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10594 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10598 private void checkTime(long startTime, String where) {
10599 long now = SystemClock.uptimeMillis();
10600 if ((now-startTime) > 50) {
10601 // If we are taking more than 50ms, log about it.
10602 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10606 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10608 PROC_SPACE_TERM|PROC_PARENS,
10609 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
10612 private final long[] mProcessStateStatsLongs = new long[1];
10614 boolean isProcessAliveLocked(ProcessRecord proc) {
10615 if (proc.procStatFile == null) {
10616 proc.procStatFile = "/proc/" + proc.pid + "/stat";
10618 mProcessStateStatsLongs[0] = 0;
10619 if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10620 mProcessStateStatsLongs, null)) {
10621 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10624 final long state = mProcessStateStatsLongs[0];
10625 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10627 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10630 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10631 String name, IBinder token, boolean stable, int userId) {
10632 ContentProviderRecord cpr;
10633 ContentProviderConnection conn = null;
10634 ProviderInfo cpi = null;
10636 synchronized(this) {
10637 long startTime = SystemClock.uptimeMillis();
10639 ProcessRecord r = null;
10640 if (caller != null) {
10641 r = getRecordForAppLocked(caller);
10643 throw new SecurityException(
10644 "Unable to find app for caller " + caller
10645 + " (pid=" + Binder.getCallingPid()
10646 + ") when getting content provider " + name);
10650 boolean checkCrossUser = true;
10652 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10654 // First check if this content provider has been published...
10655 cpr = mProviderMap.getProviderByName(name, userId);
10656 // If that didn't work, check if it exists for user 0 and then
10657 // verify that it's a singleton provider before using it.
10658 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10659 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10662 if (isSingleton(cpi.processName, cpi.applicationInfo,
10663 cpi.name, cpi.flags)
10664 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10665 userId = UserHandle.USER_SYSTEM;
10666 checkCrossUser = false;
10674 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10675 if (providerRunning) {
10678 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10679 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10681 throw new SecurityException(msg);
10683 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10685 if (r != null && cpr.canRunHere(r)) {
10686 // This provider has been published or is in the process
10687 // of being published... but it is also allowed to run
10688 // in the caller's process, so don't make a connection
10689 // and just let the caller instantiate its own instance.
10690 ContentProviderHolder holder = cpr.newHolder(null);
10691 // don't give caller the provider object, it needs
10692 // to make its own.
10693 holder.provider = null;
10697 final long origId = Binder.clearCallingIdentity();
10699 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10701 // In this case the provider instance already exists, so we can
10702 // return it right away.
10703 conn = incProviderCountLocked(r, cpr, token, stable);
10704 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10705 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10706 // If this is a perceptible app accessing the provider,
10707 // make sure to count it as being accessed and thus
10708 // back up on the LRU list. This is good because
10709 // content providers are often expensive to start.
10710 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10711 updateLruProcessLocked(cpr.proc, false, null);
10712 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10716 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10717 final int verifiedAdj = cpr.proc.verifiedAdj;
10718 boolean success = updateOomAdjLocked(cpr.proc);
10719 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10720 // if the process has been successfully adjusted. So to reduce races with
10721 // it, we will check whether the process still exists. Note that this doesn't
10722 // completely get rid of races with LMK killing the process, but should make
10723 // them much smaller.
10724 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10727 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10728 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10729 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10730 // NOTE: there is still a race here where a signal could be
10731 // pending on the process even though we managed to update its
10732 // adj level. Not sure what to do about this, but at least
10733 // the race is now smaller.
10735 // Uh oh... it looks like the provider's process
10736 // has been killed on us. We need to wait for a new
10737 // process to be started, and make sure its death
10738 // doesn't kill our process.
10739 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10740 + " is crashing; detaching " + r);
10741 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10742 checkTime(startTime, "getContentProviderImpl: before appDied");
10743 appDiedLocked(cpr.proc);
10744 checkTime(startTime, "getContentProviderImpl: after appDied");
10746 // This wasn't the last ref our process had on
10747 // the provider... we have now been killed, bail.
10750 providerRunning = false;
10753 cpr.proc.verifiedAdj = cpr.proc.setAdj;
10756 Binder.restoreCallingIdentity(origId);
10759 if (!providerRunning) {
10761 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10762 cpi = AppGlobals.getPackageManager().
10763 resolveContentProvider(name,
10764 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10765 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10766 } catch (RemoteException ex) {
10771 // If the provider is a singleton AND
10772 // (it's a call within the same user || the provider is a
10774 // Then allow connecting to the singleton provider
10775 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10776 cpi.name, cpi.flags)
10777 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10779 userId = UserHandle.USER_SYSTEM;
10781 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10782 checkTime(startTime, "getContentProviderImpl: got app info for user");
10785 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10786 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10788 throw new SecurityException(msg);
10790 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10792 if (!mProcessesReady
10793 && !cpi.processName.equals("system")) {
10794 // If this content provider does not run in the system
10795 // process, and the system is not yet ready to run other
10796 // processes, then fail fast instead of hanging.
10797 throw new IllegalArgumentException(
10798 "Attempt to launch content provider before system ready");
10801 // Make sure that the user who owns this provider is running. If not,
10802 // we don't want to allow it to run.
10803 if (!mUserController.isUserRunningLocked(userId, 0)) {
10804 Slog.w(TAG, "Unable to launch app "
10805 + cpi.applicationInfo.packageName + "/"
10806 + cpi.applicationInfo.uid + " for provider "
10807 + name + ": user " + userId + " is stopped");
10811 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10812 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10813 cpr = mProviderMap.getProviderByClass(comp, userId);
10814 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10815 final boolean firstClass = cpr == null;
10817 final long ident = Binder.clearCallingIdentity();
10819 // If permissions need a review before any of the app components can run,
10820 // we return no provider and launch a review activity if the calling app
10821 // is in the foreground.
10822 if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10823 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10829 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10830 ApplicationInfo ai =
10831 AppGlobals.getPackageManager().
10832 getApplicationInfo(
10833 cpi.applicationInfo.packageName,
10834 STOCK_PM_FLAGS, userId);
10835 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10837 Slog.w(TAG, "No package info for content provider "
10841 ai = getAppInfoForUser(ai, userId);
10842 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10843 } catch (RemoteException ex) {
10844 // pm is in same process, this will never happen.
10846 Binder.restoreCallingIdentity(ident);
10850 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10852 if (r != null && cpr.canRunHere(r)) {
10853 // If this is a multiprocess provider, then just return its
10854 // info and allow the caller to instantiate it. Only do
10855 // this if the provider is the same user as the caller's
10856 // process, or can run as root (so can be in any process).
10857 return cpr.newHolder(null);
10860 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10861 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10862 + cpr.info.name + " callers=" + Debug.getCallers(6));
10864 // This is single process, and our app is now connecting to it.
10865 // See if we are already in the process of launching this
10867 final int N = mLaunchingProviders.size();
10869 for (i = 0; i < N; i++) {
10870 if (mLaunchingProviders.get(i) == cpr) {
10875 // If the provider is not already being launched, then get it
10878 final long origId = Binder.clearCallingIdentity();
10881 // Content provider is now in use, its package can't be stopped.
10883 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10884 AppGlobals.getPackageManager().setPackageStoppedState(
10885 cpr.appInfo.packageName, false, userId);
10886 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10887 } catch (RemoteException e) {
10888 } catch (IllegalArgumentException e) {
10889 Slog.w(TAG, "Failed trying to unstop package "
10890 + cpr.appInfo.packageName + ": " + e);
10893 // Use existing process if already started
10894 checkTime(startTime, "getContentProviderImpl: looking for process record");
10895 ProcessRecord proc = getProcessRecordLocked(
10896 cpi.processName, cpr.appInfo.uid, false);
10897 if (proc != null && proc.thread != null && !proc.killed) {
10898 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10899 "Installing in existing process " + proc);
10900 if (!proc.pubProviders.containsKey(cpi.name)) {
10901 checkTime(startTime, "getContentProviderImpl: scheduling install");
10902 proc.pubProviders.put(cpi.name, cpr);
10904 proc.thread.scheduleInstallProvider(cpi);
10905 } catch (RemoteException e) {
10909 checkTime(startTime, "getContentProviderImpl: before start process");
10910 proc = startProcessLocked(cpi.processName,
10911 cpr.appInfo, false, 0, "content provider",
10912 new ComponentName(cpi.applicationInfo.packageName,
10913 cpi.name), false, false, false);
10914 checkTime(startTime, "getContentProviderImpl: after start process");
10915 if (proc == null) {
10916 Slog.w(TAG, "Unable to launch app "
10917 + cpi.applicationInfo.packageName + "/"
10918 + cpi.applicationInfo.uid + " for provider "
10919 + name + ": process is bad");
10923 cpr.launchingApp = proc;
10924 mLaunchingProviders.add(cpr);
10926 Binder.restoreCallingIdentity(origId);
10930 checkTime(startTime, "getContentProviderImpl: updating data structures");
10932 // Make sure the provider is published (the same provider class
10933 // may be published under multiple names).
10935 mProviderMap.putProviderByClass(comp, cpr);
10938 mProviderMap.putProviderByName(name, cpr);
10939 conn = incProviderCountLocked(r, cpr, token, stable);
10940 if (conn != null) {
10941 conn.waiting = true;
10944 checkTime(startTime, "getContentProviderImpl: done!");
10947 // Wait for the provider to be published...
10948 synchronized (cpr) {
10949 while (cpr.provider == null) {
10950 if (cpr.launchingApp == null) {
10951 Slog.w(TAG, "Unable to launch app "
10952 + cpi.applicationInfo.packageName + "/"
10953 + cpi.applicationInfo.uid + " for provider "
10954 + name + ": launching app became null");
10955 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10956 UserHandle.getUserId(cpi.applicationInfo.uid),
10957 cpi.applicationInfo.packageName,
10958 cpi.applicationInfo.uid, name);
10962 if (DEBUG_MU) Slog.v(TAG_MU,
10963 "Waiting to start provider " + cpr
10964 + " launchingApp=" + cpr.launchingApp);
10965 if (conn != null) {
10966 conn.waiting = true;
10969 } catch (InterruptedException ex) {
10971 if (conn != null) {
10972 conn.waiting = false;
10977 return cpr != null ? cpr.newHolder(conn) : null;
10980 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10981 ProcessRecord r, final int userId) {
10982 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10983 cpi.packageName, userId)) {
10985 final boolean callerForeground = r == null || r.setSchedGroup
10986 != ProcessList.SCHED_GROUP_BACKGROUND;
10988 // Show a permission review UI only for starting from a foreground app
10989 if (!callerForeground) {
10990 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10991 + cpi.packageName + " requires a permissions review");
10995 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10996 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10997 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10998 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11000 if (DEBUG_PERMISSIONS_REVIEW) {
11001 Slog.i(TAG, "u" + userId + " Launching permission review "
11002 + "for package " + cpi.packageName);
11005 final UserHandle userHandle = new UserHandle(userId);
11006 mHandler.post(new Runnable() {
11008 public void run() {
11009 mContext.startActivityAsUser(intent, userHandle);
11019 PackageManagerInternal getPackageManagerInternalLocked() {
11020 if (mPackageManagerInt == null) {
11021 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11023 return mPackageManagerInt;
11027 public final ContentProviderHolder getContentProvider(
11028 IApplicationThread caller, String name, int userId, boolean stable) {
11029 enforceNotIsolatedCaller("getContentProvider");
11030 if (caller == null) {
11031 String msg = "null IApplicationThread when getting content provider "
11034 throw new SecurityException(msg);
11036 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11037 // with cross-user grant.
11038 return getContentProviderImpl(caller, name, null, stable, userId);
11041 public ContentProviderHolder getContentProviderExternal(
11042 String name, int userId, IBinder token) {
11043 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11044 "Do not have permission in call getContentProviderExternal()");
11045 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11046 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11047 return getContentProviderExternalUnchecked(name, token, userId);
11050 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11051 IBinder token, int userId) {
11052 return getContentProviderImpl(null, name, token, true, userId);
11056 * Drop a content provider from a ProcessRecord's bookkeeping
11058 public void removeContentProvider(IBinder connection, boolean stable) {
11059 enforceNotIsolatedCaller("removeContentProvider");
11060 long ident = Binder.clearCallingIdentity();
11062 synchronized (this) {
11063 ContentProviderConnection conn;
11065 conn = (ContentProviderConnection)connection;
11066 } catch (ClassCastException e) {
11067 String msg ="removeContentProvider: " + connection
11068 + " not a ContentProviderConnection";
11070 throw new IllegalArgumentException(msg);
11072 if (conn == null) {
11073 throw new NullPointerException("connection is null");
11075 if (decProviderCountLocked(conn, null, null, stable)) {
11076 updateOomAdjLocked();
11080 Binder.restoreCallingIdentity(ident);
11084 public void removeContentProviderExternal(String name, IBinder token) {
11085 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11086 "Do not have permission in call removeContentProviderExternal()");
11087 int userId = UserHandle.getCallingUserId();
11088 long ident = Binder.clearCallingIdentity();
11090 removeContentProviderExternalUnchecked(name, token, userId);
11092 Binder.restoreCallingIdentity(ident);
11096 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11097 synchronized (this) {
11098 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11100 //remove from mProvidersByClass
11101 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11105 //update content provider record entry info
11106 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11107 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11108 if (localCpr.hasExternalProcessHandles()) {
11109 if (localCpr.removeExternalProcessHandleLocked(token)) {
11110 updateOomAdjLocked();
11112 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11113 + " with no external reference for token: "
11117 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11118 + " with no external references.");
11123 public final void publishContentProviders(IApplicationThread caller,
11124 List<ContentProviderHolder> providers) {
11125 if (providers == null) {
11129 enforceNotIsolatedCaller("publishContentProviders");
11130 synchronized (this) {
11131 final ProcessRecord r = getRecordForAppLocked(caller);
11132 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11134 throw new SecurityException(
11135 "Unable to find app for caller " + caller
11136 + " (pid=" + Binder.getCallingPid()
11137 + ") when publishing content providers");
11140 final long origId = Binder.clearCallingIdentity();
11142 final int N = providers.size();
11143 for (int i = 0; i < N; i++) {
11144 ContentProviderHolder src = providers.get(i);
11145 if (src == null || src.info == null || src.provider == null) {
11148 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11149 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11151 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11152 mProviderMap.putProviderByClass(comp, dst);
11153 String names[] = dst.info.authority.split(";");
11154 for (int j = 0; j < names.length; j++) {
11155 mProviderMap.putProviderByName(names[j], dst);
11158 int launchingCount = mLaunchingProviders.size();
11160 boolean wasInLaunchingProviders = false;
11161 for (j = 0; j < launchingCount; j++) {
11162 if (mLaunchingProviders.get(j) == dst) {
11163 mLaunchingProviders.remove(j);
11164 wasInLaunchingProviders = true;
11169 if (wasInLaunchingProviders) {
11170 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11172 synchronized (dst) {
11173 dst.provider = src.provider;
11177 updateOomAdjLocked(r);
11178 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11179 src.info.authority);
11183 Binder.restoreCallingIdentity(origId);
11187 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11188 ContentProviderConnection conn;
11190 conn = (ContentProviderConnection)connection;
11191 } catch (ClassCastException e) {
11192 String msg ="refContentProvider: " + connection
11193 + " not a ContentProviderConnection";
11195 throw new IllegalArgumentException(msg);
11197 if (conn == null) {
11198 throw new NullPointerException("connection is null");
11201 synchronized (this) {
11203 conn.numStableIncs += stable;
11205 stable = conn.stableCount + stable;
11207 throw new IllegalStateException("stableCount < 0: " + stable);
11210 if (unstable > 0) {
11211 conn.numUnstableIncs += unstable;
11213 unstable = conn.unstableCount + unstable;
11214 if (unstable < 0) {
11215 throw new IllegalStateException("unstableCount < 0: " + unstable);
11218 if ((stable+unstable) <= 0) {
11219 throw new IllegalStateException("ref counts can't go to zero here: stable="
11220 + stable + " unstable=" + unstable);
11222 conn.stableCount = stable;
11223 conn.unstableCount = unstable;
11228 public void unstableProviderDied(IBinder connection) {
11229 ContentProviderConnection conn;
11231 conn = (ContentProviderConnection)connection;
11232 } catch (ClassCastException e) {
11233 String msg ="refContentProvider: " + connection
11234 + " not a ContentProviderConnection";
11236 throw new IllegalArgumentException(msg);
11238 if (conn == null) {
11239 throw new NullPointerException("connection is null");
11242 // Safely retrieve the content provider associated with the connection.
11243 IContentProvider provider;
11244 synchronized (this) {
11245 provider = conn.provider.provider;
11248 if (provider == null) {
11249 // Um, yeah, we're way ahead of you.
11253 // Make sure the caller is being honest with us.
11254 if (provider.asBinder().pingBinder()) {
11255 // Er, no, still looks good to us.
11256 synchronized (this) {
11257 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11258 + " says " + conn + " died, but we don't agree");
11263 // Well look at that! It's dead!
11264 synchronized (this) {
11265 if (conn.provider.provider != provider) {
11266 // But something changed... good enough.
11270 ProcessRecord proc = conn.provider.proc;
11271 if (proc == null || proc.thread == null) {
11272 // Seems like the process is already cleaned up.
11276 // As far as we're concerned, this is just like receiving a
11277 // death notification... just a bit prematurely.
11278 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11279 + ") early provider death");
11280 final long ident = Binder.clearCallingIdentity();
11282 appDiedLocked(proc);
11284 Binder.restoreCallingIdentity(ident);
11290 public void appNotRespondingViaProvider(IBinder connection) {
11291 enforceCallingPermission(
11292 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11294 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11295 if (conn == null) {
11296 Slog.w(TAG, "ContentProviderConnection is null");
11300 final ProcessRecord host = conn.provider.proc;
11301 if (host == null) {
11302 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11306 mHandler.post(new Runnable() {
11308 public void run() {
11309 mAppErrors.appNotResponding(host, null, null, false,
11310 "ContentProvider not responding");
11315 public final void installSystemProviders() {
11316 List<ProviderInfo> providers;
11317 synchronized (this) {
11318 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11319 providers = generateApplicationProvidersLocked(app);
11320 if (providers != null) {
11321 for (int i=providers.size()-1; i>=0; i--) {
11322 ProviderInfo pi = (ProviderInfo)providers.get(i);
11323 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11324 Slog.w(TAG, "Not installing system proc provider " + pi.name
11325 + ": not system .apk");
11326 providers.remove(i);
11331 if (providers != null) {
11332 mSystemThread.installSystemProviders(providers);
11335 mCoreSettingsObserver = new CoreSettingsObserver(this);
11336 mFontScaleSettingObserver = new FontScaleSettingObserver();
11338 //mUsageStatsService.monitorPackages();
11341 private void startPersistentApps(int matchFlags) {
11342 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11344 synchronized (this) {
11346 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11347 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11348 for (ApplicationInfo app : apps) {
11349 if (!"android".equals(app.packageName)) {
11350 addAppLocked(app, false, null /* ABI override */);
11353 } catch (RemoteException ex) {
11359 * When a user is unlocked, we need to install encryption-unaware providers
11360 * belonging to any running apps.
11362 private void installEncryptionUnawareProviders(int userId) {
11363 // We're only interested in providers that are encryption unaware, and
11364 // we don't care about uninstalled apps, since there's no way they're
11365 // running at this point.
11366 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11368 synchronized (this) {
11369 final int NP = mProcessNames.getMap().size();
11370 for (int ip = 0; ip < NP; ip++) {
11371 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11372 final int NA = apps.size();
11373 for (int ia = 0; ia < NA; ia++) {
11374 final ProcessRecord app = apps.valueAt(ia);
11375 if (app.userId != userId || app.thread == null || app.unlocked) continue;
11377 final int NG = app.pkgList.size();
11378 for (int ig = 0; ig < NG; ig++) {
11380 final String pkgName = app.pkgList.keyAt(ig);
11381 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11382 .getPackageInfo(pkgName, matchFlags, userId);
11383 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11384 for (ProviderInfo pi : pkgInfo.providers) {
11385 // TODO: keep in sync with generateApplicationProvidersLocked
11386 final boolean processMatch = Objects.equals(pi.processName,
11387 app.processName) || pi.multiprocess;
11388 final boolean userMatch = isSingleton(pi.processName,
11389 pi.applicationInfo, pi.name, pi.flags)
11390 ? (app.userId == UserHandle.USER_SYSTEM) : true;
11391 if (processMatch && userMatch) {
11392 Log.v(TAG, "Installing " + pi);
11393 app.thread.scheduleInstallProvider(pi);
11395 Log.v(TAG, "Skipping " + pi);
11399 } catch (RemoteException ignored) {
11408 * Allows apps to retrieve the MIME type of a URI.
11409 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11410 * users, then it does not need permission to access the ContentProvider.
11411 * Either, it needs cross-user uri grants.
11413 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11415 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11416 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11418 public String getProviderMimeType(Uri uri, int userId) {
11419 enforceNotIsolatedCaller("getProviderMimeType");
11420 final String name = uri.getAuthority();
11421 int callingUid = Binder.getCallingUid();
11422 int callingPid = Binder.getCallingPid();
11424 boolean clearedIdentity = false;
11425 synchronized (this) {
11426 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11428 if (canClearIdentity(callingPid, callingUid, userId)) {
11429 clearedIdentity = true;
11430 ident = Binder.clearCallingIdentity();
11432 ContentProviderHolder holder = null;
11434 holder = getContentProviderExternalUnchecked(name, null, userId);
11435 if (holder != null) {
11436 return holder.provider.getType(uri);
11438 } catch (RemoteException e) {
11439 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11441 } catch (Exception e) {
11442 Log.w(TAG, "Exception while determining type of " + uri, e);
11445 // We need to clear the identity to call removeContentProviderExternalUnchecked
11446 if (!clearedIdentity) {
11447 ident = Binder.clearCallingIdentity();
11450 if (holder != null) {
11451 removeContentProviderExternalUnchecked(name, null, userId);
11454 Binder.restoreCallingIdentity(ident);
11461 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11462 if (UserHandle.getUserId(callingUid) == userId) {
11465 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11466 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11467 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11468 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11474 // =========================================================
11475 // GLOBAL MANAGEMENT
11476 // =========================================================
11478 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11479 boolean isolated, int isolatedUid) {
11480 String proc = customProcess != null ? customProcess : info.processName;
11481 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11482 final int userId = UserHandle.getUserId(info.uid);
11483 int uid = info.uid;
11485 if (isolatedUid == 0) {
11486 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11488 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11489 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11490 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11492 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11493 mNextIsolatedProcessUid++;
11494 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11495 // No process for this uid, use it.
11499 if (stepsLeft <= 0) {
11504 // Special case for startIsolatedProcess (internal only), where
11505 // the uid of the isolated process is specified by the caller.
11509 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11510 if (!mBooted && !mBooting
11511 && userId == UserHandle.USER_SYSTEM
11512 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11513 r.persistent = true;
11515 addProcessNameLocked(r);
11519 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11520 String abiOverride) {
11523 app = getProcessRecordLocked(info.processName, info.uid, true);
11529 app = newProcessRecordLocked(info, null, isolated, 0);
11530 updateLruProcessLocked(app, false, null);
11531 updateOomAdjLocked();
11534 // This package really, really can not be stopped.
11536 AppGlobals.getPackageManager().setPackageStoppedState(
11537 info.packageName, false, UserHandle.getUserId(app.uid));
11538 } catch (RemoteException e) {
11539 } catch (IllegalArgumentException e) {
11540 Slog.w(TAG, "Failed trying to unstop package "
11541 + info.packageName + ": " + e);
11544 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11545 app.persistent = true;
11546 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11548 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11549 mPersistentStartingProcesses.add(app);
11550 startProcessLocked(app, "added application", app.processName, abiOverride,
11551 null /* entryPoint */, null /* entryPointArgs */);
11557 public void unhandledBack() {
11558 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11559 "unhandledBack()");
11561 synchronized(this) {
11562 final long origId = Binder.clearCallingIdentity();
11564 getFocusedStack().unhandledBackLocked();
11566 Binder.restoreCallingIdentity(origId);
11571 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11572 enforceNotIsolatedCaller("openContentUri");
11573 final int userId = UserHandle.getCallingUserId();
11574 String name = uri.getAuthority();
11575 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11576 ParcelFileDescriptor pfd = null;
11578 // We record the binder invoker's uid in thread-local storage before
11579 // going to the content provider to open the file. Later, in the code
11580 // that handles all permissions checks, we look for this uid and use
11581 // that rather than the Activity Manager's own uid. The effect is that
11582 // we do the check against the caller's permissions even though it looks
11583 // to the content provider like the Activity Manager itself is making
11585 Binder token = new Binder();
11586 sCallerIdentity.set(new Identity(
11587 token, Binder.getCallingPid(), Binder.getCallingUid()));
11589 pfd = cph.provider.openFile(null, uri, "r", null, token);
11590 } catch (FileNotFoundException e) {
11591 // do nothing; pfd will be returned null
11593 // Ensure that whatever happens, we clean up the identity state
11594 sCallerIdentity.remove();
11595 // Ensure we're done with the provider.
11596 removeContentProviderExternalUnchecked(name, null, userId);
11599 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11604 // Actually is sleeping or shutting down or whatever else in the future
11605 // is an inactive state.
11606 boolean isSleepingOrShuttingDownLocked() {
11607 return isSleepingLocked() || mShuttingDown;
11610 boolean isShuttingDownLocked() {
11611 return mShuttingDown;
11614 boolean isSleepingLocked() {
11618 void onWakefulnessChanged(int wakefulness) {
11619 synchronized(this) {
11620 mWakefulness = wakefulness;
11621 updateSleepIfNeededLocked();
11625 void finishRunningVoiceLocked() {
11626 if (mRunningVoice != null) {
11627 mRunningVoice = null;
11628 mVoiceWakeLock.release();
11629 updateSleepIfNeededLocked();
11633 void startTimeTrackingFocusedActivityLocked() {
11634 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11635 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11639 void updateSleepIfNeededLocked() {
11640 if (mSleeping && !shouldSleepLocked()) {
11642 startTimeTrackingFocusedActivityLocked();
11643 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11644 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11645 updateOomAdjLocked();
11646 } else if (!mSleeping && shouldSleepLocked()) {
11648 if (mCurAppTimeTracker != null) {
11649 mCurAppTimeTracker.stop();
11651 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11652 mStackSupervisor.goingToSleepLocked();
11653 updateOomAdjLocked();
11655 // Initialize the wake times of all processes.
11656 checkExcessivePowerUsageLocked(false);
11657 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11658 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11659 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11663 private boolean shouldSleepLocked() {
11664 // Resume applications while running a voice interactor.
11665 if (mRunningVoice != null) {
11669 // TODO: Transform the lock screen state into a sleep token instead.
11670 switch (mWakefulness) {
11671 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11672 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11673 case PowerManagerInternal.WAKEFULNESS_DOZING:
11674 // Pause applications whenever the lock screen is shown or any sleep
11675 // tokens have been acquired.
11676 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11677 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11679 // If we're asleep then pause applications unconditionally.
11684 /** Pokes the task persister. */
11685 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11686 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11689 /** Notifies all listeners when the task stack has changed. */
11690 void notifyTaskStackChangedLocked() {
11691 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11692 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11693 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11694 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11697 /** Notifies all listeners when an Activity is pinned. */
11698 void notifyActivityPinnedLocked() {
11699 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11700 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11704 * Notifies all listeners when an attempt was made to start an an activity that is already
11705 * running in the pinned stack and the activity was not actually started, but the task is
11706 * either brought to the front or a new Intent is delivered to it.
11708 void notifyPinnedActivityRestartAttemptLocked() {
11709 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11710 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11713 /** Notifies all listeners when the pinned stack animation ends. */
11715 public void notifyPinnedStackAnimationEnded() {
11716 synchronized (this) {
11717 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11718 mHandler.obtainMessage(
11719 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11724 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11725 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11729 public boolean shutdown(int timeout) {
11730 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11731 != PackageManager.PERMISSION_GRANTED) {
11732 throw new SecurityException("Requires permission "
11733 + android.Manifest.permission.SHUTDOWN);
11736 boolean timedout = false;
11738 synchronized(this) {
11739 mShuttingDown = true;
11740 updateEventDispatchingLocked();
11741 timedout = mStackSupervisor.shutdownLocked(timeout);
11744 mAppOpsService.shutdown();
11745 if (mUsageStatsService != null) {
11746 mUsageStatsService.prepareShutdown();
11748 mBatteryStatsService.shutdown();
11749 synchronized (this) {
11750 mProcessStats.shutdownLocked();
11751 notifyTaskPersisterLocked(null, true);
11757 public final void activitySlept(IBinder token) {
11758 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11760 final long origId = Binder.clearCallingIdentity();
11762 synchronized (this) {
11763 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11765 mStackSupervisor.activitySleptLocked(r);
11769 Binder.restoreCallingIdentity(origId);
11772 private String lockScreenShownToString() {
11773 switch (mLockScreenShown) {
11774 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11775 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11776 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11777 default: return "Unknown=" + mLockScreenShown;
11781 void logLockScreen(String msg) {
11782 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11783 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11784 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11785 + " mSleeping=" + mSleeping);
11788 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11789 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11790 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11791 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11792 boolean wasRunningVoice = mRunningVoice != null;
11793 mRunningVoice = session;
11794 if (!wasRunningVoice) {
11795 mVoiceWakeLock.acquire();
11796 updateSleepIfNeededLocked();
11801 private void updateEventDispatchingLocked() {
11802 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11805 public void setLockScreenShown(boolean showing, boolean occluded) {
11806 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11807 != PackageManager.PERMISSION_GRANTED) {
11808 throw new SecurityException("Requires permission "
11809 + android.Manifest.permission.DEVICE_POWER);
11812 synchronized(this) {
11813 long ident = Binder.clearCallingIdentity();
11815 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11816 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11817 if (showing && occluded) {
11818 // The lock screen is currently showing, but is occluded by a window that can
11819 // show on top of the lock screen. In this can we want to dismiss the docked
11820 // stack since it will be complicated/risky to try to put the activity on top
11821 // of the lock screen in the right fullscreen configuration.
11822 mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11823 mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11826 updateSleepIfNeededLocked();
11828 Binder.restoreCallingIdentity(ident);
11834 public void notifyLockedProfile(@UserIdInt int userId) {
11836 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11837 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11839 } catch (RemoteException ex) {
11840 throw new SecurityException("Fail to check is caller a privileged app", ex);
11843 synchronized (this) {
11844 if (mStackSupervisor.isUserLockedProfile(userId)) {
11845 final long ident = Binder.clearCallingIdentity();
11847 final int currentUserId = mUserController.getCurrentUserIdLocked();
11849 // Drop locked freeform tasks out into the fullscreen stack.
11850 // TODO: Redact the tasks in place. It's much better to keep them on the screen
11851 // where they were before, but in an obscured state.
11852 mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11854 if (mUserController.isLockScreenDisabled(currentUserId)) {
11855 // If there is no device lock, we will show the profile's credential page.
11856 mActivityStarter.showConfirmDeviceCredential(userId);
11858 // Showing launcher to avoid user entering credential twice.
11859 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11862 Binder.restoreCallingIdentity(ident);
11869 public void startConfirmDeviceCredentialIntent(Intent intent) {
11870 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11871 synchronized (this) {
11872 final long ident = Binder.clearCallingIdentity();
11874 mActivityStarter.startConfirmCredentialIntent(intent);
11876 Binder.restoreCallingIdentity(ident);
11882 public void stopAppSwitches() {
11883 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11884 != PackageManager.PERMISSION_GRANTED) {
11885 throw new SecurityException("viewquires permission "
11886 + android.Manifest.permission.STOP_APP_SWITCHES);
11889 synchronized(this) {
11890 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11891 + APP_SWITCH_DELAY_TIME;
11892 mDidAppSwitch = false;
11893 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11894 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11895 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11899 public void resumeAppSwitches() {
11900 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11901 != PackageManager.PERMISSION_GRANTED) {
11902 throw new SecurityException("Requires permission "
11903 + android.Manifest.permission.STOP_APP_SWITCHES);
11906 synchronized(this) {
11907 // Note that we don't execute any pending app switches... we will
11908 // let those wait until either the timeout, or the next start
11909 // activity request.
11910 mAppSwitchesAllowedTime = 0;
11914 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11915 int callingPid, int callingUid, String name) {
11916 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11920 int perm = checkComponentPermission(
11921 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11922 sourceUid, -1, true);
11923 if (perm == PackageManager.PERMISSION_GRANTED) {
11927 // If the actual IPC caller is different from the logical source, then
11928 // also see if they are allowed to control app switches.
11929 if (callingUid != -1 && callingUid != sourceUid) {
11930 perm = checkComponentPermission(
11931 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11932 callingUid, -1, true);
11933 if (perm == PackageManager.PERMISSION_GRANTED) {
11938 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11942 public void setDebugApp(String packageName, boolean waitForDebugger,
11943 boolean persistent) {
11944 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11947 long ident = Binder.clearCallingIdentity();
11949 // Note that this is not really thread safe if there are multiple
11950 // callers into it at the same time, but that's not a situation we
11953 final ContentResolver resolver = mContext.getContentResolver();
11954 Settings.Global.putString(
11955 resolver, Settings.Global.DEBUG_APP,
11957 Settings.Global.putInt(
11958 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11959 waitForDebugger ? 1 : 0);
11962 synchronized (this) {
11964 mOrigDebugApp = mDebugApp;
11965 mOrigWaitForDebugger = mWaitForDebugger;
11967 mDebugApp = packageName;
11968 mWaitForDebugger = waitForDebugger;
11969 mDebugTransient = !persistent;
11970 if (packageName != null) {
11971 forceStopPackageLocked(packageName, -1, false, false, true, true,
11972 false, UserHandle.USER_ALL, "set debug app");
11976 Binder.restoreCallingIdentity(ident);
11980 void setTrackAllocationApp(ApplicationInfo app, String processName) {
11981 synchronized (this) {
11982 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11983 if (!isDebuggable) {
11984 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11985 throw new SecurityException("Process not debuggable: " + app.packageName);
11989 mTrackAllocationApp = processName;
11993 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11994 synchronized (this) {
11995 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11996 if (!isDebuggable) {
11997 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11998 throw new SecurityException("Process not debuggable: " + app.packageName);
12001 mProfileApp = processName;
12002 mProfileFile = profilerInfo.profileFile;
12003 if (mProfileFd != null) {
12005 mProfileFd.close();
12006 } catch (IOException e) {
12010 mProfileFd = profilerInfo.profileFd;
12011 mSamplingInterval = profilerInfo.samplingInterval;
12012 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12017 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12018 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12019 if (!isDebuggable) {
12020 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12021 throw new SecurityException("Process not debuggable: " + app.packageName);
12024 mNativeDebuggingApp = processName;
12028 public void setAlwaysFinish(boolean enabled) {
12029 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12030 "setAlwaysFinish()");
12032 long ident = Binder.clearCallingIdentity();
12034 Settings.Global.putInt(
12035 mContext.getContentResolver(),
12036 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12038 synchronized (this) {
12039 mAlwaysFinishActivities = enabled;
12042 Binder.restoreCallingIdentity(ident);
12047 public void setLenientBackgroundCheck(boolean enabled) {
12048 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12049 "setLenientBackgroundCheck()");
12051 long ident = Binder.clearCallingIdentity();
12053 Settings.Global.putInt(
12054 mContext.getContentResolver(),
12055 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12057 synchronized (this) {
12058 mLenientBackgroundCheck = enabled;
12061 Binder.restoreCallingIdentity(ident);
12066 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12067 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12068 "setActivityController()");
12069 synchronized (this) {
12070 mController = controller;
12071 mControllerIsAMonkey = imAMonkey;
12072 Watchdog.getInstance().setActivityController(controller);
12077 public void setUserIsMonkey(boolean userIsMonkey) {
12078 synchronized (this) {
12079 synchronized (mPidsSelfLocked) {
12080 final int callingPid = Binder.getCallingPid();
12081 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12082 if (precessRecord == null) {
12083 throw new SecurityException("Unknown process: " + callingPid);
12085 if (precessRecord.instrumentationUiAutomationConnection == null) {
12086 throw new SecurityException("Only an instrumentation process "
12087 + "with a UiAutomation can call setUserIsMonkey");
12090 mUserIsMonkey = userIsMonkey;
12095 public boolean isUserAMonkey() {
12096 synchronized (this) {
12097 // If there is a controller also implies the user is a monkey.
12098 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12102 public void requestBugReport(int bugreportType) {
12103 String service = null;
12104 switch (bugreportType) {
12105 case ActivityManager.BUGREPORT_OPTION_FULL:
12106 service = "bugreport";
12108 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12109 service = "bugreportplus";
12111 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12112 service = "bugreportremote";
12115 if (service == null) {
12116 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12119 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12120 SystemProperties.set("ctl.start", service);
12123 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12124 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12127 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12128 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12129 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12131 return KEY_DISPATCHING_TIMEOUT;
12135 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12136 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12137 != PackageManager.PERMISSION_GRANTED) {
12138 throw new SecurityException("Requires permission "
12139 + android.Manifest.permission.FILTER_EVENTS);
12141 ProcessRecord proc;
12143 synchronized (this) {
12144 synchronized (mPidsSelfLocked) {
12145 proc = mPidsSelfLocked.get(pid);
12147 timeout = getInputDispatchingTimeoutLocked(proc);
12150 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12158 * Handle input dispatching timeouts.
12159 * Returns whether input dispatching should be aborted or not.
12161 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12162 final ActivityRecord activity, final ActivityRecord parent,
12163 final boolean aboveSystem, String reason) {
12164 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12165 != PackageManager.PERMISSION_GRANTED) {
12166 throw new SecurityException("Requires permission "
12167 + android.Manifest.permission.FILTER_EVENTS);
12170 final String annotation;
12171 if (reason == null) {
12172 annotation = "Input dispatching timed out";
12174 annotation = "Input dispatching timed out (" + reason + ")";
12177 if (proc != null) {
12178 synchronized (this) {
12179 if (proc.debugging) {
12184 // Give more time since we were dexopting.
12185 mDidDexOpt = false;
12189 if (proc.instrumentationClass != null) {
12190 Bundle info = new Bundle();
12191 info.putString("shortMsg", "keyDispatchingTimedOut");
12192 info.putString("longMsg", annotation);
12193 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12197 mHandler.post(new Runnable() {
12199 public void run() {
12200 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12209 public Bundle getAssistContextExtras(int requestType) {
12210 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12211 null, null, true /* focused */, true /* newSessionId */,
12212 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12216 synchronized (pae) {
12217 while (!pae.haveResult) {
12220 } catch (InterruptedException e) {
12224 synchronized (this) {
12225 buildAssistBundleLocked(pae, pae.result);
12226 mPendingAssistExtras.remove(pae);
12227 mUiHandler.removeCallbacks(pae);
12233 public boolean isAssistDataAllowedOnCurrentActivity() {
12235 synchronized (this) {
12236 userId = mUserController.getCurrentUserIdLocked();
12237 ActivityRecord activity = getFocusedStack().topActivity();
12238 if (activity == null) {
12241 userId = activity.userId;
12243 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12244 Context.DEVICE_POLICY_SERVICE);
12245 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12249 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12250 long ident = Binder.clearCallingIdentity();
12252 synchronized (this) {
12253 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12254 ActivityRecord top = getFocusedStack().topActivity();
12255 if (top != caller) {
12256 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12257 + " is not current top " + top);
12260 if (!top.nowVisible) {
12261 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12262 + " is not visible");
12266 AssistUtils utils = new AssistUtils(mContext);
12267 return utils.showSessionForActiveService(args,
12268 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12270 Binder.restoreCallingIdentity(ident);
12275 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12276 Bundle receiverExtras,
12277 IBinder activityToken, boolean focused, boolean newSessionId) {
12278 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12279 activityToken, focused, newSessionId,
12280 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12284 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12285 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12286 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12287 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12288 "enqueueAssistContext()");
12289 synchronized (this) {
12290 ActivityRecord activity = getFocusedStack().topActivity();
12291 if (activity == null) {
12292 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12295 if (activity.app == null || activity.app.thread == null) {
12296 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12300 if (activityToken != null) {
12301 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12302 if (activity != caller) {
12303 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12304 + " is not current top " + activity);
12309 activity = ActivityRecord.forTokenLocked(activityToken);
12310 if (activity == null) {
12311 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12312 + " couldn't be found");
12317 PendingAssistExtras pae;
12318 Bundle extras = new Bundle();
12319 if (args != null) {
12320 extras.putAll(args);
12322 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12323 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12324 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12326 // Increment the sessionId if necessary
12327 if (newSessionId) {
12331 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12332 requestType, mViSessionId);
12333 mPendingAssistExtras.add(pae);
12334 mUiHandler.postDelayed(pae, timeout);
12335 } catch (RemoteException e) {
12336 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12343 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12344 IResultReceiver receiver;
12345 synchronized (this) {
12346 mPendingAssistExtras.remove(pae);
12347 receiver = pae.receiver;
12349 if (receiver != null) {
12350 // Caller wants result sent back to them.
12351 Bundle sendBundle = new Bundle();
12352 // At least return the receiver extras
12353 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12354 pae.receiverExtras);
12356 pae.receiver.send(0, sendBundle);
12357 } catch (RemoteException e) {
12362 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12363 if (result != null) {
12364 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12366 if (pae.hint != null) {
12367 pae.extras.putBoolean(pae.hint, true);
12371 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12372 AssistContent content, Uri referrer) {
12373 PendingAssistExtras pae = (PendingAssistExtras)token;
12374 synchronized (pae) {
12375 pae.result = extras;
12376 pae.structure = structure;
12377 pae.content = content;
12378 if (referrer != null) {
12379 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12381 pae.haveResult = true;
12383 if (pae.intent == null && pae.receiver == null) {
12384 // Caller is just waiting for the result.
12389 // We are now ready to launch the assist activity.
12390 IResultReceiver sendReceiver = null;
12391 Bundle sendBundle = null;
12392 synchronized (this) {
12393 buildAssistBundleLocked(pae, extras);
12394 boolean exists = mPendingAssistExtras.remove(pae);
12395 mUiHandler.removeCallbacks(pae);
12400 if ((sendReceiver=pae.receiver) != null) {
12401 // Caller wants result sent back to them.
12402 sendBundle = new Bundle();
12403 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12404 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12405 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12406 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12407 pae.receiverExtras);
12410 if (sendReceiver != null) {
12412 sendReceiver.send(0, sendBundle);
12413 } catch (RemoteException e) {
12418 long ident = Binder.clearCallingIdentity();
12420 pae.intent.replaceExtras(pae.extras);
12421 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12422 | Intent.FLAG_ACTIVITY_SINGLE_TOP
12423 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12424 closeSystemDialogs("assist");
12426 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12427 } catch (ActivityNotFoundException e) {
12428 Slog.w(TAG, "No activity to handle assist action.", e);
12431 Binder.restoreCallingIdentity(ident);
12435 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12437 return enqueueAssistContext(requestType, intent, hint, null, null, null,
12438 true /* focused */, true /* newSessionId */,
12439 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12442 public void registerProcessObserver(IProcessObserver observer) {
12443 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12444 "registerProcessObserver()");
12445 synchronized (this) {
12446 mProcessObservers.register(observer);
12451 public void unregisterProcessObserver(IProcessObserver observer) {
12452 synchronized (this) {
12453 mProcessObservers.unregister(observer);
12458 public void registerUidObserver(IUidObserver observer, int which) {
12459 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12460 "registerUidObserver()");
12461 synchronized (this) {
12462 mUidObservers.register(observer, which);
12467 public void unregisterUidObserver(IUidObserver observer) {
12468 synchronized (this) {
12469 mUidObservers.unregister(observer);
12474 public boolean convertFromTranslucent(IBinder token) {
12475 final long origId = Binder.clearCallingIdentity();
12477 synchronized (this) {
12478 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12482 final boolean translucentChanged = r.changeWindowTranslucency(true);
12483 if (translucentChanged) {
12484 r.task.stack.releaseBackgroundResources(r);
12485 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12487 mWindowManager.setAppFullscreen(token, true);
12488 return translucentChanged;
12491 Binder.restoreCallingIdentity(origId);
12496 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12497 final long origId = Binder.clearCallingIdentity();
12499 synchronized (this) {
12500 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12504 int index = r.task.mActivities.lastIndexOf(r);
12506 ActivityRecord under = r.task.mActivities.get(index - 1);
12507 under.returningOptions = options;
12509 final boolean translucentChanged = r.changeWindowTranslucency(false);
12510 if (translucentChanged) {
12511 r.task.stack.convertActivityToTranslucent(r);
12513 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12514 mWindowManager.setAppFullscreen(token, false);
12515 return translucentChanged;
12518 Binder.restoreCallingIdentity(origId);
12523 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12524 final long origId = Binder.clearCallingIdentity();
12526 synchronized (this) {
12527 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12529 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12534 Binder.restoreCallingIdentity(origId);
12539 public boolean isBackgroundVisibleBehind(IBinder token) {
12540 final long origId = Binder.clearCallingIdentity();
12542 synchronized (this) {
12543 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12544 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12545 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12546 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12550 Binder.restoreCallingIdentity(origId);
12555 public ActivityOptions getActivityOptions(IBinder token) {
12556 final long origId = Binder.clearCallingIdentity();
12558 synchronized (this) {
12559 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12561 final ActivityOptions activityOptions = r.pendingOptions;
12562 r.pendingOptions = null;
12563 return activityOptions;
12568 Binder.restoreCallingIdentity(origId);
12573 public void setImmersive(IBinder token, boolean immersive) {
12574 synchronized(this) {
12575 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12577 throw new IllegalArgumentException();
12579 r.immersive = immersive;
12581 // update associated state if we're frontmost
12582 if (r == mFocusedActivity) {
12583 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12584 applyUpdateLockStateLocked(r);
12590 public boolean isImmersive(IBinder token) {
12591 synchronized (this) {
12592 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12594 throw new IllegalArgumentException();
12596 return r.immersive;
12601 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12602 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12603 throw new UnsupportedOperationException("VR mode not supported on this device!");
12606 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12609 synchronized (this) {
12610 r = ActivityRecord.isInStackLocked(token);
12614 throw new IllegalArgumentException();
12618 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12619 VrManagerInternal.NO_ERROR) {
12623 synchronized(this) {
12624 r.requestedVrComponent = (enabled) ? packageName : null;
12626 // Update associated state if this activity is currently focused
12627 if (r == mFocusedActivity) {
12628 applyUpdateVrModeLocked(r);
12635 public boolean isVrModePackageEnabled(ComponentName packageName) {
12636 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12637 throw new UnsupportedOperationException("VR mode not supported on this device!");
12640 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12642 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12643 VrManagerInternal.NO_ERROR;
12646 public boolean isTopActivityImmersive() {
12647 enforceNotIsolatedCaller("startActivity");
12648 synchronized (this) {
12649 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12650 return (r != null) ? r.immersive : false;
12655 public boolean isTopOfTask(IBinder token) {
12656 synchronized (this) {
12657 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12659 throw new IllegalArgumentException();
12661 return r.task.getTopActivity() == r;
12665 public final void enterSafeMode() {
12666 synchronized(this) {
12667 // It only makes sense to do this before the system is ready
12668 // and started launching other packages.
12669 if (!mSystemReady) {
12671 AppGlobals.getPackageManager().enterSafeMode();
12672 } catch (RemoteException e) {
12680 public final void showSafeModeOverlay() {
12681 View v = LayoutInflater.from(mContext).inflate(
12682 com.android.internal.R.layout.safe_mode, null);
12683 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12684 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12685 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12686 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12687 lp.gravity = Gravity.BOTTOM | Gravity.START;
12688 lp.format = v.getBackground().getOpacity();
12689 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12690 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12691 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12692 ((WindowManager)mContext.getSystemService(
12693 Context.WINDOW_SERVICE)).addView(v, lp);
12696 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12697 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12700 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12701 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12702 synchronized (stats) {
12703 if (mBatteryStatsService.isOnBattery()) {
12704 mBatteryStatsService.enforceCallingPermission();
12705 int MY_UID = Binder.getCallingUid();
12707 if (sender == null) {
12710 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12712 BatteryStatsImpl.Uid.Pkg pkg =
12713 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12714 sourcePkg != null ? sourcePkg : rec.key.packageName);
12715 pkg.noteWakeupAlarmLocked(tag);
12720 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12721 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12724 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12725 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12726 synchronized (stats) {
12727 mBatteryStatsService.enforceCallingPermission();
12728 int MY_UID = Binder.getCallingUid();
12730 if (sender == null) {
12733 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12735 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12739 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12740 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12743 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12744 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12745 synchronized (stats) {
12746 mBatteryStatsService.enforceCallingPermission();
12747 int MY_UID = Binder.getCallingUid();
12749 if (sender == null) {
12752 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12754 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12758 public boolean killPids(int[] pids, String pReason, boolean secure) {
12759 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12760 throw new SecurityException("killPids only available to the system");
12762 String reason = (pReason == null) ? "Unknown" : pReason;
12763 // XXX Note: don't acquire main activity lock here, because the window
12764 // manager calls in with its locks held.
12766 boolean killed = false;
12767 synchronized (mPidsSelfLocked) {
12769 for (int i=0; i<pids.length; i++) {
12770 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12771 if (proc != null) {
12772 int type = proc.setAdj;
12773 if (type > worstType) {
12779 // If the worst oom_adj is somewhere in the cached proc LRU range,
12780 // then constrain it so we will kill all cached procs.
12781 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12782 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12783 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12786 // If this is not a secure call, don't let it kill processes that
12788 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12789 worstType = ProcessList.SERVICE_ADJ;
12792 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12793 for (int i=0; i<pids.length; i++) {
12794 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12795 if (proc == null) {
12798 int adj = proc.setAdj;
12799 if (adj >= worstType && !proc.killedByAm) {
12800 proc.kill(reason, true);
12809 public void killUid(int appId, int userId, String reason) {
12810 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12811 synchronized (this) {
12812 final long identity = Binder.clearCallingIdentity();
12814 killPackageProcessesLocked(null, appId, userId,
12815 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12816 reason != null ? reason : "kill uid");
12818 Binder.restoreCallingIdentity(identity);
12824 public boolean killProcessesBelowForeground(String reason) {
12825 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12826 throw new SecurityException("killProcessesBelowForeground() only available to system");
12829 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12832 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12833 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12834 throw new SecurityException("killProcessesBelowAdj() only available to system");
12837 boolean killed = false;
12838 synchronized (mPidsSelfLocked) {
12839 final int size = mPidsSelfLocked.size();
12840 for (int i = 0; i < size; i++) {
12841 final int pid = mPidsSelfLocked.keyAt(i);
12842 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12843 if (proc == null) continue;
12845 final int adj = proc.setAdj;
12846 if (adj > belowAdj && !proc.killedByAm) {
12847 proc.kill(reason, true);
12856 public void hang(final IBinder who, boolean allowRestart) {
12857 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12858 != PackageManager.PERMISSION_GRANTED) {
12859 throw new SecurityException("Requires permission "
12860 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12863 final IBinder.DeathRecipient death = new DeathRecipient() {
12865 public void binderDied() {
12866 synchronized (this) {
12873 who.linkToDeath(death, 0);
12874 } catch (RemoteException e) {
12875 Slog.w(TAG, "hang: given caller IBinder is already dead.");
12879 synchronized (this) {
12880 Watchdog.getInstance().setAllowRestart(allowRestart);
12881 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12882 synchronized (death) {
12883 while (who.isBinderAlive()) {
12886 } catch (InterruptedException e) {
12890 Watchdog.getInstance().setAllowRestart(true);
12895 public void restart() {
12896 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12897 != PackageManager.PERMISSION_GRANTED) {
12898 throw new SecurityException("Requires permission "
12899 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12902 Log.i(TAG, "Sending shutdown broadcast...");
12904 BroadcastReceiver br = new BroadcastReceiver() {
12905 @Override public void onReceive(Context context, Intent intent) {
12906 // Now the broadcast is done, finish up the low-level shutdown.
12907 Log.i(TAG, "Shutting down activity manager...");
12909 Log.i(TAG, "Shutdown complete, restarting!");
12910 Process.killProcess(Process.myPid());
12915 // First send the high-level shut down broadcast.
12916 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12917 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12918 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12919 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12920 mContext.sendOrderedBroadcastAsUser(intent,
12921 UserHandle.ALL, null, br, mHandler, 0, null, null);
12923 br.onReceive(mContext, intent);
12926 private long getLowRamTimeSinceIdle(long now) {
12927 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12931 public void performIdleMaintenance() {
12932 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12933 != PackageManager.PERMISSION_GRANTED) {
12934 throw new SecurityException("Requires permission "
12935 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12938 synchronized (this) {
12939 final long now = SystemClock.uptimeMillis();
12940 final long timeSinceLastIdle = now - mLastIdleTime;
12941 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12942 mLastIdleTime = now;
12943 mLowRamTimeSinceLastIdle = 0;
12944 if (mLowRamStartTime != 0) {
12945 mLowRamStartTime = now;
12948 StringBuilder sb = new StringBuilder(128);
12949 sb.append("Idle maintenance over ");
12950 TimeUtils.formatDuration(timeSinceLastIdle, sb);
12951 sb.append(" low RAM for ");
12952 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12953 Slog.i(TAG, sb.toString());
12955 // If at least 1/3 of our time since the last idle period has been spent
12956 // with RAM low, then we want to kill processes.
12957 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12959 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12960 ProcessRecord proc = mLruProcesses.get(i);
12961 if (proc.notCachedSinceIdle) {
12962 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12963 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12964 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12965 if (doKilling && proc.initialIdlePss != 0
12966 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12967 sb = new StringBuilder(128);
12969 sb.append(proc.processName);
12970 sb.append(" in idle maint: pss=");
12971 sb.append(proc.lastPss);
12972 sb.append(", swapPss=");
12973 sb.append(proc.lastSwapPss);
12974 sb.append(", initialPss=");
12975 sb.append(proc.initialIdlePss);
12976 sb.append(", period=");
12977 TimeUtils.formatDuration(timeSinceLastIdle, sb);
12978 sb.append(", lowRamPeriod=");
12979 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12980 Slog.wtfQuiet(TAG, sb.toString());
12981 proc.kill("idle maint (pss " + proc.lastPss
12982 + " from " + proc.initialIdlePss + ")", true);
12985 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12986 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12987 proc.notCachedSinceIdle = true;
12988 proc.initialIdlePss = 0;
12989 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12990 mTestPssMode, isSleepingLocked(), now);
12994 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12995 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13000 public void sendIdleJobTrigger() {
13001 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13002 != PackageManager.PERMISSION_GRANTED) {
13003 throw new SecurityException("Requires permission "
13004 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13007 final long ident = Binder.clearCallingIdentity();
13009 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13010 .setPackage("android")
13011 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13012 broadcastIntent(null, intent, null, null, 0, null, null, null,
13013 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13015 Binder.restoreCallingIdentity(ident);
13019 private void retrieveSettings() {
13020 final ContentResolver resolver = mContext.getContentResolver();
13021 final boolean freeformWindowManagement =
13022 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13023 || Settings.Global.getInt(
13024 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13025 final boolean supportsPictureInPicture =
13026 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13028 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13029 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13030 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13031 final boolean alwaysFinishActivities =
13032 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13033 final boolean lenientBackgroundCheck =
13034 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13035 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13036 final boolean forceResizable = Settings.Global.getInt(
13037 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13038 final boolean supportsLeanbackOnly =
13039 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13041 // Transfer any global setting for forcing RTL layout, into a System Property
13042 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13044 final Configuration configuration = new Configuration();
13045 Settings.System.getConfiguration(resolver, configuration);
13047 // This will take care of setting the correct layout direction flags
13048 configuration.setLayoutDirection(configuration.locale);
13051 synchronized (this) {
13052 mDebugApp = mOrigDebugApp = debugApp;
13053 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13054 mAlwaysFinishActivities = alwaysFinishActivities;
13055 mLenientBackgroundCheck = lenientBackgroundCheck;
13056 mSupportsLeanbackOnly = supportsLeanbackOnly;
13057 mForceResizableActivities = forceResizable;
13058 mWindowManager.setForceResizableTasks(mForceResizableActivities);
13059 if (supportsMultiWindow || forceResizable) {
13060 mSupportsMultiWindow = true;
13061 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13062 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13064 mSupportsMultiWindow = false;
13065 mSupportsFreeformWindowManagement = false;
13066 mSupportsPictureInPicture = false;
13068 // This happens before any activities are started, so we can
13069 // change mConfiguration in-place.
13070 updateConfigurationLocked(configuration, null, true);
13071 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13072 "Initial config: " + mConfiguration);
13074 // Load resources only after the current configuration has been set.
13075 final Resources res = mContext.getResources();
13076 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13077 mThumbnailWidth = res.getDimensionPixelSize(
13078 com.android.internal.R.dimen.thumbnail_width);
13079 mThumbnailHeight = res.getDimensionPixelSize(
13080 com.android.internal.R.dimen.thumbnail_height);
13081 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13082 com.android.internal.R.string.config_defaultPictureInPictureBounds));
13083 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13084 com.android.internal.R.string.config_appsNotReportingCrashes));
13085 if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13086 mFullscreenThumbnailScale = (float) res
13087 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13088 (float) mConfiguration.screenWidthDp;
13090 mFullscreenThumbnailScale = res.getFraction(
13091 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13096 public boolean testIsSystemReady() {
13097 // no need to synchronize(this) just to read & return the value
13098 return mSystemReady;
13101 public void systemReady(final Runnable goingCallback) {
13102 synchronized(this) {
13103 if (mSystemReady) {
13104 // If we're done calling all the receivers, run the next "boot phase" passed in
13105 // by the SystemServer
13106 if (goingCallback != null) {
13107 goingCallback.run();
13112 mLocalDeviceIdleController
13113 = LocalServices.getService(DeviceIdleController.LocalService.class);
13115 // Make sure we have the current profile info, since it is needed for security checks.
13116 mUserController.onSystemReady();
13117 mRecentTasks.onSystemReadyLocked();
13118 mAppOpsService.systemReady();
13119 mSystemReady = true;
13122 ArrayList<ProcessRecord> procsToKill = null;
13123 synchronized(mPidsSelfLocked) {
13124 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13125 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13126 if (!isAllowedWhileBooting(proc.info)){
13127 if (procsToKill == null) {
13128 procsToKill = new ArrayList<ProcessRecord>();
13130 procsToKill.add(proc);
13135 synchronized(this) {
13136 if (procsToKill != null) {
13137 for (int i=procsToKill.size()-1; i>=0; i--) {
13138 ProcessRecord proc = procsToKill.get(i);
13139 Slog.i(TAG, "Removing system update proc: " + proc);
13140 removeProcessLocked(proc, true, false, "system update done");
13144 // Now that we have cleaned up any update processes, we
13145 // are ready to start launching real processes and know that
13146 // we won't trample on them any more.
13147 mProcessesReady = true;
13150 Slog.i(TAG, "System now ready");
13151 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13152 SystemClock.uptimeMillis());
13154 synchronized(this) {
13155 // Make sure we have no pre-ready processes sitting around.
13157 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13158 ResolveInfo ri = mContext.getPackageManager()
13159 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13161 CharSequence errorMsg = null;
13163 ActivityInfo ai = ri.activityInfo;
13164 ApplicationInfo app = ai.applicationInfo;
13165 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13166 mTopAction = Intent.ACTION_FACTORY_TEST;
13168 mTopComponent = new ComponentName(app.packageName,
13171 errorMsg = mContext.getResources().getText(
13172 com.android.internal.R.string.factorytest_not_system);
13175 errorMsg = mContext.getResources().getText(
13176 com.android.internal.R.string.factorytest_no_action);
13178 if (errorMsg != null) {
13181 mTopComponent = null;
13182 Message msg = Message.obtain();
13183 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13184 msg.getData().putCharSequence("msg", errorMsg);
13185 mUiHandler.sendMessage(msg);
13190 retrieveSettings();
13191 final int currentUserId;
13192 synchronized (this) {
13193 currentUserId = mUserController.getCurrentUserIdLocked();
13194 readGrantedUriPermissionsLocked();
13197 if (goingCallback != null) goingCallback.run();
13199 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13200 Integer.toString(currentUserId), currentUserId);
13201 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13202 Integer.toString(currentUserId), currentUserId);
13203 mSystemServiceManager.startUser(currentUserId);
13205 synchronized (this) {
13206 // Only start up encryption-aware persistent apps; once user is
13207 // unlocked we'll come back around and start unaware apps
13208 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13210 // Start up initial activity.
13212 // Enable home activity for system user, so that the system can always boot
13213 if (UserManager.isSplitSystemUser()) {
13214 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13216 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13217 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13218 UserHandle.USER_SYSTEM);
13219 } catch (RemoteException e) {
13220 throw e.rethrowAsRuntimeException();
13223 startHomeActivityLocked(currentUserId, "systemReady");
13226 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13227 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13228 + " data partition or your device will be unstable.");
13229 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13231 } catch (RemoteException e) {
13234 if (!Build.isBuildConsistent()) {
13235 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13236 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13239 long ident = Binder.clearCallingIdentity();
13241 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13242 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13243 | Intent.FLAG_RECEIVER_FOREGROUND);
13244 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13245 broadcastIntentLocked(null, null, intent,
13246 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13247 null, false, false, MY_PID, Process.SYSTEM_UID,
13249 intent = new Intent(Intent.ACTION_USER_STARTING);
13250 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13251 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13252 broadcastIntentLocked(null, null, intent,
13253 null, new IIntentReceiver.Stub() {
13255 public void performReceive(Intent intent, int resultCode, String data,
13256 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13257 throws RemoteException {
13260 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13261 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13262 } catch (Throwable t) {
13263 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13265 Binder.restoreCallingIdentity(ident);
13267 mStackSupervisor.resumeFocusedStackTopActivityLocked();
13268 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13272 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13273 synchronized (this) {
13274 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13278 void skipCurrentReceiverLocked(ProcessRecord app) {
13279 for (BroadcastQueue queue : mBroadcastQueues) {
13280 queue.skipCurrentReceiverLocked(app);
13285 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13286 * The application process will exit immediately after this call returns.
13287 * @param app object of the crashing app, null for the system server
13288 * @param crashInfo describing the exception
13290 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13291 ProcessRecord r = findAppProcess(app, "Crash");
13292 final String processName = app == null ? "system_server"
13293 : (r == null ? "unknown" : r.processName);
13295 handleApplicationCrashInner("crash", r, processName, crashInfo);
13298 /* Native crash reporting uses this inner version because it needs to be somewhat
13299 * decoupled from the AM-managed cleanup lifecycle
13301 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13302 ApplicationErrorReport.CrashInfo crashInfo) {
13303 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13304 UserHandle.getUserId(Binder.getCallingUid()), processName,
13305 r == null ? -1 : r.info.flags,
13306 crashInfo.exceptionClassName,
13307 crashInfo.exceptionMessage,
13308 crashInfo.throwFileName,
13309 crashInfo.throwLineNumber);
13311 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13313 mAppErrors.crashApplication(r, crashInfo);
13316 public void handleApplicationStrictModeViolation(
13319 StrictMode.ViolationInfo info) {
13320 ProcessRecord r = findAppProcess(app, "StrictMode");
13325 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13326 Integer stackFingerprint = info.hashCode();
13327 boolean logIt = true;
13328 synchronized (mAlreadyLoggedViolatedStacks) {
13329 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13331 // TODO: sub-sample into EventLog for these, with
13332 // the info.durationMillis? Then we'd get
13333 // the relative pain numbers, without logging all
13334 // the stack traces repeatedly. We'd want to do
13335 // likewise in the client code, which also does
13336 // dup suppression, before the Binder call.
13338 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13339 mAlreadyLoggedViolatedStacks.clear();
13341 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13345 logStrictModeViolationToDropBox(r, info);
13349 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13350 AppErrorResult result = new AppErrorResult();
13351 synchronized (this) {
13352 final long origId = Binder.clearCallingIdentity();
13354 Message msg = Message.obtain();
13355 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13356 HashMap<String, Object> data = new HashMap<String, Object>();
13357 data.put("result", result);
13358 data.put("app", r);
13359 data.put("violationMask", violationMask);
13360 data.put("info", info);
13362 mUiHandler.sendMessage(msg);
13364 Binder.restoreCallingIdentity(origId);
13366 int res = result.get();
13367 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13371 // Depending on the policy in effect, there could be a bunch of
13372 // these in quick succession so we try to batch these together to
13373 // minimize disk writes, number of dropbox entries, and maximize
13374 // compression, by having more fewer, larger records.
13375 private void logStrictModeViolationToDropBox(
13376 ProcessRecord process,
13377 StrictMode.ViolationInfo info) {
13378 if (info == null) {
13381 final boolean isSystemApp = process == null ||
13382 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13383 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13384 final String processName = process == null ? "unknown" : process.processName;
13385 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13386 final DropBoxManager dbox = (DropBoxManager)
13387 mContext.getSystemService(Context.DROPBOX_SERVICE);
13389 // Exit early if the dropbox isn't configured to accept this report type.
13390 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13392 boolean bufferWasEmpty;
13393 boolean needsFlush;
13394 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13395 synchronized (sb) {
13396 bufferWasEmpty = sb.length() == 0;
13397 appendDropBoxProcessHeaders(process, processName, sb);
13398 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13399 sb.append("System-App: ").append(isSystemApp).append("\n");
13400 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13401 if (info.violationNumThisLoop != 0) {
13402 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13404 if (info.numAnimationsRunning != 0) {
13405 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13407 if (info.broadcastIntentAction != null) {
13408 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13410 if (info.durationMillis != -1) {
13411 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13413 if (info.numInstances != -1) {
13414 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13416 if (info.tags != null) {
13417 for (String tag : info.tags) {
13418 sb.append("Span-Tag: ").append(tag).append("\n");
13422 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13423 sb.append(info.crashInfo.stackTrace);
13426 if (info.message != null) {
13427 sb.append(info.message);
13431 // Only buffer up to ~64k. Various logging bits truncate
13433 needsFlush = (sb.length() > 64 * 1024);
13436 // Flush immediately if the buffer's grown too large, or this
13437 // is a non-system app. Non-system apps are isolated with a
13438 // different tag & policy and not batched.
13440 // Batching is useful during internal testing with
13441 // StrictMode settings turned up high. Without batching,
13442 // thousands of separate files could be created on boot.
13443 if (!isSystemApp || needsFlush) {
13444 new Thread("Error dump: " + dropboxTag) {
13446 public void run() {
13448 synchronized (sb) {
13449 report = sb.toString();
13450 sb.delete(0, sb.length());
13453 if (report.length() != 0) {
13454 dbox.addText(dropboxTag, report);
13461 // System app batching:
13462 if (!bufferWasEmpty) {
13463 // An existing dropbox-writing thread is outstanding, so
13464 // we don't need to start it up. The existing thread will
13465 // catch the buffer appends we just did.
13469 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13470 // (After this point, we shouldn't access AMS internal data structures.)
13471 new Thread("Error dump: " + dropboxTag) {
13473 public void run() {
13474 // 5 second sleep to let stacks arrive and be batched together
13476 Thread.sleep(5000); // 5 seconds
13477 } catch (InterruptedException e) {}
13479 String errorReport;
13480 synchronized (mStrictModeBuffer) {
13481 errorReport = mStrictModeBuffer.toString();
13482 if (errorReport.length() == 0) {
13485 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13486 mStrictModeBuffer.trimToSize();
13488 dbox.addText(dropboxTag, errorReport);
13494 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13495 * @param app object of the crashing app, null for the system server
13496 * @param tag reported by the caller
13497 * @param system whether this wtf is coming from the system
13498 * @param crashInfo describing the context of the error
13499 * @return true if the process should exit immediately (WTF is fatal)
13501 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13502 final ApplicationErrorReport.CrashInfo crashInfo) {
13503 final int callingUid = Binder.getCallingUid();
13504 final int callingPid = Binder.getCallingPid();
13507 // If this is coming from the system, we could very well have low-level
13508 // system locks held, so we want to do this all asynchronously. And we
13509 // never want this to become fatal, so there is that too.
13510 mHandler.post(new Runnable() {
13511 @Override public void run() {
13512 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13518 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13521 if (r != null && r.pid != Process.myPid() &&
13522 Settings.Global.getInt(mContext.getContentResolver(),
13523 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13524 mAppErrors.crashApplication(r, crashInfo);
13531 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13532 final ApplicationErrorReport.CrashInfo crashInfo) {
13533 final ProcessRecord r = findAppProcess(app, "WTF");
13534 final String processName = app == null ? "system_server"
13535 : (r == null ? "unknown" : r.processName);
13537 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13538 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13540 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13546 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13547 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13549 private ProcessRecord findAppProcess(IBinder app, String reason) {
13554 synchronized (this) {
13555 final int NP = mProcessNames.getMap().size();
13556 for (int ip=0; ip<NP; ip++) {
13557 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13558 final int NA = apps.size();
13559 for (int ia=0; ia<NA; ia++) {
13560 ProcessRecord p = apps.valueAt(ia);
13561 if (p.thread != null && p.thread.asBinder() == app) {
13567 Slog.w(TAG, "Can't find mystery application for " + reason
13568 + " from pid=" + Binder.getCallingPid()
13569 + " uid=" + Binder.getCallingUid() + ": " + app);
13575 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13576 * to append various headers to the dropbox log text.
13578 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13579 StringBuilder sb) {
13580 // Watchdog thread ends up invoking this function (with
13581 // a null ProcessRecord) to add the stack file to dropbox.
13582 // Do not acquire a lock on this (am) in such cases, as it
13583 // could cause a potential deadlock, if and when watchdog
13584 // is invoked due to unavailability of lock on am and it
13585 // would prevent watchdog from killing system_server.
13586 if (process == null) {
13587 sb.append("Process: ").append(processName).append("\n");
13590 // Note: ProcessRecord 'process' is guarded by the service
13591 // instance. (notably process.pkgList, which could otherwise change
13592 // concurrently during execution of this method)
13593 synchronized (this) {
13594 sb.append("Process: ").append(processName).append("\n");
13595 int flags = process.info.flags;
13596 IPackageManager pm = AppGlobals.getPackageManager();
13597 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13598 for (int ip=0; ip<process.pkgList.size(); ip++) {
13599 String pkg = process.pkgList.keyAt(ip);
13600 sb.append("Package: ").append(pkg);
13602 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13604 sb.append(" v").append(pi.versionCode);
13605 if (pi.versionName != null) {
13606 sb.append(" (").append(pi.versionName).append(")");
13609 } catch (RemoteException e) {
13610 Slog.e(TAG, "Error getting package info: " + pkg, e);
13617 private static String processClass(ProcessRecord process) {
13618 if (process == null || process.pid == MY_PID) {
13619 return "system_server";
13620 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13621 return "system_app";
13627 private volatile long mWtfClusterStart;
13628 private volatile int mWtfClusterCount;
13631 * Write a description of an error (crash, WTF, ANR) to the drop box.
13632 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13633 * @param process which caused the error, null means the system server
13634 * @param activity which triggered the error, null if unknown
13635 * @param parent activity related to the error, null if unknown
13636 * @param subject line related to the error, null if absent
13637 * @param report in long form describing the error, null if absent
13638 * @param dataFile text file to include in the report, null if none
13639 * @param crashInfo giving an application stack trace, null if absent
13641 public void addErrorToDropBox(String eventType,
13642 ProcessRecord process, String processName, ActivityRecord activity,
13643 ActivityRecord parent, String subject,
13644 final String report, final File dataFile,
13645 final ApplicationErrorReport.CrashInfo crashInfo) {
13646 // NOTE -- this must never acquire the ActivityManagerService lock,
13647 // otherwise the watchdog may be prevented from resetting the system.
13649 final String dropboxTag = processClass(process) + "_" + eventType;
13650 final DropBoxManager dbox = (DropBoxManager)
13651 mContext.getSystemService(Context.DROPBOX_SERVICE);
13653 // Exit early if the dropbox isn't configured to accept this report type.
13654 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13656 // Rate-limit how often we're willing to do the heavy lifting below to
13657 // collect and record logs; currently 5 logs per 10 second period.
13658 final long now = SystemClock.elapsedRealtime();
13659 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13660 mWtfClusterStart = now;
13661 mWtfClusterCount = 1;
13663 if (mWtfClusterCount++ >= 5) return;
13666 final StringBuilder sb = new StringBuilder(1024);
13667 appendDropBoxProcessHeaders(process, processName, sb);
13668 if (process != null) {
13669 sb.append("Foreground: ")
13670 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13673 if (activity != null) {
13674 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13676 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13677 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13679 if (parent != null && parent != activity) {
13680 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13682 if (subject != null) {
13683 sb.append("Subject: ").append(subject).append("\n");
13685 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13686 if (Debug.isDebuggerConnected()) {
13687 sb.append("Debugger: Connected\n");
13691 // Do the rest in a worker thread to avoid blocking the caller on I/O
13692 // (After this point, we shouldn't access AMS internal data structures.)
13693 Thread worker = new Thread("Error dump: " + dropboxTag) {
13695 public void run() {
13696 if (report != null) {
13700 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13701 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13702 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13703 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13705 if (dataFile != null && maxDataFileSize > 0) {
13707 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13708 "\n\n[[TRUNCATED]]"));
13709 } catch (IOException e) {
13710 Slog.e(TAG, "Error reading " + dataFile, e);
13713 if (crashInfo != null && crashInfo.stackTrace != null) {
13714 sb.append(crashInfo.stackTrace);
13720 // Merge several logcat streams, and take the last N lines
13721 InputStreamReader input = null;
13723 java.lang.Process logcat = new ProcessBuilder(
13724 "/system/bin/timeout", "-k", "15s", "10s",
13725 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13726 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13727 .redirectErrorStream(true).start();
13729 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13730 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13731 input = new InputStreamReader(logcat.getInputStream());
13734 char[] buf = new char[8192];
13735 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13736 } catch (IOException e) {
13737 Slog.e(TAG, "Error running logcat", e);
13739 if (input != null) try { input.close(); } catch (IOException e) {}
13743 dbox.addText(dropboxTag, sb.toString());
13747 if (process == null) {
13748 // If process is null, we are being called from some internal code
13749 // and may be about to die -- run this synchronously.
13757 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13758 enforceNotIsolatedCaller("getProcessesInErrorState");
13759 // assume our apps are happy - lazy create the list
13760 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13762 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13763 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13764 int userId = UserHandle.getUserId(Binder.getCallingUid());
13766 synchronized (this) {
13768 // iterate across all processes
13769 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13770 ProcessRecord app = mLruProcesses.get(i);
13771 if (!allUsers && app.userId != userId) {
13774 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13775 // This one's in trouble, so we'll generate a report for it
13776 // crashes are higher priority (in case there's a crash *and* an anr)
13777 ActivityManager.ProcessErrorStateInfo report = null;
13778 if (app.crashing) {
13779 report = app.crashingReport;
13780 } else if (app.notResponding) {
13781 report = app.notRespondingReport;
13784 if (report != null) {
13785 if (errList == null) {
13786 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13788 errList.add(report);
13790 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13791 " crashing = " + app.crashing +
13792 " notResponding = " + app.notResponding);
13801 static int procStateToImportance(int procState, int memAdj,
13802 ActivityManager.RunningAppProcessInfo currApp) {
13803 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13804 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13805 currApp.lru = memAdj;
13812 private void fillInProcMemInfo(ProcessRecord app,
13813 ActivityManager.RunningAppProcessInfo outInfo) {
13814 outInfo.pid = app.pid;
13815 outInfo.uid = app.info.uid;
13816 if (mHeavyWeightProcess == app) {
13817 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13819 if (app.persistent) {
13820 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13822 if (app.activities.size() > 0) {
13823 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13825 outInfo.lastTrimLevel = app.trimMemoryLevel;
13826 int adj = app.curAdj;
13827 int procState = app.curProcState;
13828 outInfo.importance = procStateToImportance(procState, adj, outInfo);
13829 outInfo.importanceReasonCode = app.adjTypeCode;
13830 outInfo.processState = app.curProcState;
13834 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13835 enforceNotIsolatedCaller("getRunningAppProcesses");
13837 final int callingUid = Binder.getCallingUid();
13839 // Lazy instantiation of list
13840 List<ActivityManager.RunningAppProcessInfo> runList = null;
13841 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13842 callingUid) == PackageManager.PERMISSION_GRANTED;
13843 final int userId = UserHandle.getUserId(callingUid);
13844 final boolean allUids = isGetTasksAllowed(
13845 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13847 synchronized (this) {
13848 // Iterate across all processes
13849 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13850 ProcessRecord app = mLruProcesses.get(i);
13851 if ((!allUsers && app.userId != userId)
13852 || (!allUids && app.uid != callingUid)) {
13855 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13856 // Generate process state info for running application
13857 ActivityManager.RunningAppProcessInfo currApp =
13858 new ActivityManager.RunningAppProcessInfo(app.processName,
13859 app.pid, app.getPackageList());
13860 fillInProcMemInfo(app, currApp);
13861 if (app.adjSource instanceof ProcessRecord) {
13862 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13863 currApp.importanceReasonImportance =
13864 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13865 app.adjSourceProcState);
13866 } else if (app.adjSource instanceof ActivityRecord) {
13867 ActivityRecord r = (ActivityRecord)app.adjSource;
13868 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13870 if (app.adjTarget instanceof ComponentName) {
13871 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13873 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13874 // + " lru=" + currApp.lru);
13875 if (runList == null) {
13876 runList = new ArrayList<>();
13878 runList.add(currApp);
13886 public List<ApplicationInfo> getRunningExternalApplications() {
13887 enforceNotIsolatedCaller("getRunningExternalApplications");
13888 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13889 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13890 if (runningApps != null && runningApps.size() > 0) {
13891 Set<String> extList = new HashSet<String>();
13892 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13893 if (app.pkgList != null) {
13894 for (String pkg : app.pkgList) {
13899 IPackageManager pm = AppGlobals.getPackageManager();
13900 for (String pkg : extList) {
13902 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13903 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13906 } catch (RemoteException e) {
13914 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13915 enforceNotIsolatedCaller("getMyMemoryState");
13916 synchronized (this) {
13917 ProcessRecord proc;
13918 synchronized (mPidsSelfLocked) {
13919 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13921 fillInProcMemInfo(proc, outInfo);
13926 public int getMemoryTrimLevel() {
13927 enforceNotIsolatedCaller("getMyMemoryState");
13928 synchronized (this) {
13929 return mLastMemoryLevel;
13934 public void onShellCommand(FileDescriptor in, FileDescriptor out,
13935 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13936 (new ActivityManagerShellCommand(this, false)).exec(
13937 this, in, out, err, args, resultReceiver);
13941 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13942 if (checkCallingPermission(android.Manifest.permission.DUMP)
13943 != PackageManager.PERMISSION_GRANTED) {
13944 pw.println("Permission Denial: can't dump ActivityManager from from pid="
13945 + Binder.getCallingPid()
13946 + ", uid=" + Binder.getCallingUid()
13947 + " without permission "
13948 + android.Manifest.permission.DUMP);
13952 boolean dumpAll = false;
13953 boolean dumpClient = false;
13954 boolean dumpCheckin = false;
13955 boolean dumpCheckinFormat = false;
13956 String dumpPackage = null;
13959 while (opti < args.length) {
13960 String opt = args[opti];
13961 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13965 if ("-a".equals(opt)) {
13967 } else if ("-c".equals(opt)) {
13969 } else if ("-p".equals(opt)) {
13970 if (opti < args.length) {
13971 dumpPackage = args[opti];
13974 pw.println("Error: -p option requires package argument");
13978 } else if ("--checkin".equals(opt)) {
13979 dumpCheckin = dumpCheckinFormat = true;
13980 } else if ("-C".equals(opt)) {
13981 dumpCheckinFormat = true;
13982 } else if ("-h".equals(opt)) {
13983 ActivityManagerShellCommand.dumpHelp(pw, true);
13986 pw.println("Unknown argument: " + opt + "; use -h for help");
13990 long origId = Binder.clearCallingIdentity();
13991 boolean more = false;
13992 // Is the caller requesting to dump a particular piece of data?
13993 if (opti < args.length) {
13994 String cmd = args[opti];
13996 if ("activities".equals(cmd) || "a".equals(cmd)) {
13997 synchronized (this) {
13998 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14000 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14001 synchronized (this) {
14002 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14004 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14007 if (opti >= args.length) {
14009 newArgs = EMPTY_STRING_ARRAY;
14011 dumpPackage = args[opti];
14013 newArgs = new String[args.length - opti];
14014 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14015 args.length - opti);
14017 synchronized (this) {
14018 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14020 } else if ("broadcast-stats".equals(cmd)) {
14023 if (opti >= args.length) {
14025 newArgs = EMPTY_STRING_ARRAY;
14027 dumpPackage = args[opti];
14029 newArgs = new String[args.length - opti];
14030 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14031 args.length - opti);
14033 synchronized (this) {
14034 if (dumpCheckinFormat) {
14035 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14038 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14041 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14044 if (opti >= args.length) {
14046 newArgs = EMPTY_STRING_ARRAY;
14048 dumpPackage = args[opti];
14050 newArgs = new String[args.length - opti];
14051 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14052 args.length - opti);
14054 synchronized (this) {
14055 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14057 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14060 if (opti >= args.length) {
14062 newArgs = EMPTY_STRING_ARRAY;
14064 dumpPackage = args[opti];
14066 newArgs = new String[args.length - opti];
14067 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14068 args.length - opti);
14070 synchronized (this) {
14071 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14073 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14074 synchronized (this) {
14075 dumpOomLocked(fd, pw, args, opti, true);
14077 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14078 synchronized (this) {
14079 dumpPermissionsLocked(fd, pw, args, opti, true, null);
14081 } else if ("provider".equals(cmd)) {
14084 if (opti >= args.length) {
14086 newArgs = EMPTY_STRING_ARRAY;
14090 newArgs = new String[args.length - opti];
14091 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14093 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14094 pw.println("No providers match: " + name);
14095 pw.println("Use -h for help.");
14097 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14098 synchronized (this) {
14099 dumpProvidersLocked(fd, pw, args, opti, true, null);
14101 } else if ("service".equals(cmd)) {
14104 if (opti >= args.length) {
14106 newArgs = EMPTY_STRING_ARRAY;
14110 newArgs = new String[args.length - opti];
14111 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14112 args.length - opti);
14114 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14115 pw.println("No services match: " + name);
14116 pw.println("Use -h for help.");
14118 } else if ("package".equals(cmd)) {
14120 if (opti >= args.length) {
14121 pw.println("package: no package name specified");
14122 pw.println("Use -h for help.");
14124 dumpPackage = args[opti];
14126 newArgs = new String[args.length - opti];
14127 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14128 args.length - opti);
14133 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14134 synchronized (this) {
14135 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14137 } else if ("services".equals(cmd) || "s".equals(cmd)) {
14139 ActiveServices.ServiceDumper dumper;
14140 synchronized (this) {
14141 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14144 dumper.dumpWithClient();
14146 synchronized (this) {
14147 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14148 dumpPackage).dumpLocked();
14151 } else if ("locks".equals(cmd)) {
14152 LockGuard.dump(fd, pw, args);
14154 // Dumping a single activity?
14155 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14156 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14157 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14159 pw.println("Bad activity command, or no activities match: " + cmd);
14160 pw.println("Use -h for help.");
14165 Binder.restoreCallingIdentity(origId);
14170 // No piece of data specified, dump everything.
14171 if (dumpCheckinFormat) {
14172 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14173 } else if (dumpClient) {
14174 ActiveServices.ServiceDumper sdumper;
14175 synchronized (this) {
14176 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14179 pw.println("-------------------------------------------------------------------------------");
14181 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14184 pw.println("-------------------------------------------------------------------------------");
14186 if (dumpAll || dumpPackage != null) {
14187 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14190 pw.println("-------------------------------------------------------------------------------");
14193 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14196 pw.println("-------------------------------------------------------------------------------");
14198 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14201 pw.println("-------------------------------------------------------------------------------");
14203 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14206 sdumper.dumpWithClient();
14208 synchronized (this) {
14210 pw.println("-------------------------------------------------------------------------------");
14212 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14215 pw.println("-------------------------------------------------------------------------------");
14217 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14218 if (mAssociations.size() > 0) {
14221 pw.println("-------------------------------------------------------------------------------");
14223 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14227 pw.println("-------------------------------------------------------------------------------");
14229 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14233 synchronized (this) {
14234 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14237 pw.println("-------------------------------------------------------------------------------");
14239 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14242 pw.println("-------------------------------------------------------------------------------");
14244 if (dumpAll || dumpPackage != null) {
14245 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14248 pw.println("-------------------------------------------------------------------------------");
14251 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14254 pw.println("-------------------------------------------------------------------------------");
14256 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14259 pw.println("-------------------------------------------------------------------------------");
14261 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14265 pw.println("-------------------------------------------------------------------------------");
14267 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14270 pw.println("-------------------------------------------------------------------------------");
14272 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14273 if (mAssociations.size() > 0) {
14276 pw.println("-------------------------------------------------------------------------------");
14278 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14282 pw.println("-------------------------------------------------------------------------------");
14284 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14287 Binder.restoreCallingIdentity(origId);
14290 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14291 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14292 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14294 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14296 boolean needSep = printedAnything;
14298 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14299 dumpPackage, needSep, " mFocusedActivity: ");
14301 printedAnything = true;
14305 if (dumpPackage == null) {
14310 printedAnything = true;
14311 mStackSupervisor.dump(pw, " ");
14314 if (!printedAnything) {
14315 pw.println(" (nothing)");
14319 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14320 int opti, boolean dumpAll, String dumpPackage) {
14321 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14323 boolean printedAnything = false;
14325 if (mRecentTasks != null && mRecentTasks.size() > 0) {
14326 boolean printedHeader = false;
14328 final int N = mRecentTasks.size();
14329 for (int i=0; i<N; i++) {
14330 TaskRecord tr = mRecentTasks.get(i);
14331 if (dumpPackage != null) {
14332 if (tr.realActivity == null ||
14333 !dumpPackage.equals(tr.realActivity)) {
14337 if (!printedHeader) {
14338 pw.println(" Recent tasks:");
14339 printedHeader = true;
14340 printedAnything = true;
14342 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
14345 mRecentTasks.get(i).dump(pw, " ");
14350 if (!printedAnything) {
14351 pw.println(" (nothing)");
14355 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14356 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14357 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14360 if (dumpPackage != null) {
14361 IPackageManager pm = AppGlobals.getPackageManager();
14363 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14364 } catch (RemoteException e) {
14368 boolean printedAnything = false;
14370 final long now = SystemClock.uptimeMillis();
14372 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14373 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14374 = mAssociations.valueAt(i1);
14375 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14376 SparseArray<ArrayMap<String, Association>> sourceUids
14377 = targetComponents.valueAt(i2);
14378 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14379 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14380 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14381 Association ass = sourceProcesses.valueAt(i4);
14382 if (dumpPackage != null) {
14383 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14384 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14388 printedAnything = true;
14390 pw.print(ass.mTargetProcess);
14392 UserHandle.formatUid(pw, ass.mTargetUid);
14394 pw.print(ass.mSourceProcess);
14396 UserHandle.formatUid(pw, ass.mSourceUid);
14399 pw.print(ass.mTargetComponent.flattenToShortString());
14402 long dur = ass.mTime;
14403 if (ass.mNesting > 0) {
14404 dur += now - ass.mStartTime;
14406 TimeUtils.formatDuration(dur, pw);
14408 pw.print(ass.mCount);
14409 pw.print(" times)");
14411 for (int i=0; i<ass.mStateTimes.length; i++) {
14412 long amt = ass.mStateTimes[i];
14413 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14414 amt += now - ass.mLastStateUptime;
14418 pw.print(ProcessList.makeProcStateString(
14419 i + ActivityManager.MIN_PROCESS_STATE));
14421 TimeUtils.formatDuration(amt, pw);
14422 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14428 if (ass.mNesting > 0) {
14429 pw.print(" Currently active: ");
14430 TimeUtils.formatDuration(now - ass.mStartTime, pw);
14439 if (!printedAnything) {
14440 pw.println(" (nothing)");
14444 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14445 String header, boolean needSep) {
14446 boolean printed = false;
14447 int whichAppId = -1;
14448 if (dumpPackage != null) {
14450 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14452 whichAppId = UserHandle.getAppId(info.uid);
14453 } catch (NameNotFoundException e) {
14454 e.printStackTrace();
14457 for (int i=0; i<uids.size(); i++) {
14458 UidRecord uidRec = uids.valueAt(i);
14459 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14468 pw.println(header);
14471 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14472 pw.print(": "); pw.println(uidRec);
14477 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14478 int opti, boolean dumpAll, String dumpPackage) {
14479 boolean needSep = false;
14480 boolean printedAnything = false;
14483 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14486 final int NP = mProcessNames.getMap().size();
14487 for (int ip=0; ip<NP; ip++) {
14488 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14489 final int NA = procs.size();
14490 for (int ia=0; ia<NA; ia++) {
14491 ProcessRecord r = procs.valueAt(ia);
14492 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14496 pw.println(" All known processes:");
14498 printedAnything = true;
14500 pw.print(r.persistent ? " *PERS*" : " *APP*");
14501 pw.print(" UID "); pw.print(procs.keyAt(ia));
14502 pw.print(" "); pw.println(r);
14504 if (r.persistent) {
14511 if (mIsolatedProcesses.size() > 0) {
14512 boolean printed = false;
14513 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14514 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14515 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14522 pw.println(" Isolated process list (sorted by uid):");
14523 printedAnything = true;
14527 pw.println(String.format("%sIsolated #%2d: %s",
14528 " ", i, r.toString()));
14532 if (mActiveUids.size() > 0) {
14533 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14534 printedAnything = needSep = true;
14537 if (mValidateUids.size() > 0) {
14538 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14539 printedAnything = needSep = true;
14543 if (mLruProcesses.size() > 0) {
14547 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14548 pw.print(" total, non-act at ");
14549 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14550 pw.print(", non-svc at ");
14551 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14553 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14555 printedAnything = true;
14558 if (dumpAll || dumpPackage != null) {
14559 synchronized (mPidsSelfLocked) {
14560 boolean printed = false;
14561 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14562 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14563 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14567 if (needSep) pw.println();
14569 pw.println(" PID mappings:");
14571 printedAnything = true;
14573 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14574 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14579 if (mForegroundProcesses.size() > 0) {
14580 synchronized (mPidsSelfLocked) {
14581 boolean printed = false;
14582 for (int i=0; i<mForegroundProcesses.size(); i++) {
14583 ProcessRecord r = mPidsSelfLocked.get(
14584 mForegroundProcesses.valueAt(i).pid);
14585 if (dumpPackage != null && (r == null
14586 || !r.pkgList.containsKey(dumpPackage))) {
14590 if (needSep) pw.println();
14592 pw.println(" Foreground Processes:");
14594 printedAnything = true;
14596 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14597 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14602 if (mPersistentStartingProcesses.size() > 0) {
14603 if (needSep) pw.println();
14605 printedAnything = true;
14606 pw.println(" Persisent processes that are starting:");
14607 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14608 "Starting Norm", "Restarting PERS", dumpPackage);
14611 if (mRemovedProcesses.size() > 0) {
14612 if (needSep) pw.println();
14614 printedAnything = true;
14615 pw.println(" Processes that are being removed:");
14616 dumpProcessList(pw, this, mRemovedProcesses, " ",
14617 "Removed Norm", "Removed PERS", dumpPackage);
14620 if (mProcessesOnHold.size() > 0) {
14621 if (needSep) pw.println();
14623 printedAnything = true;
14624 pw.println(" Processes that are on old until the system is ready:");
14625 dumpProcessList(pw, this, mProcessesOnHold, " ",
14626 "OnHold Norm", "OnHold PERS", dumpPackage);
14629 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14631 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14633 printedAnything = true;
14636 if (dumpPackage == null) {
14639 mUserController.dump(pw, dumpAll);
14641 if (mHomeProcess != null && (dumpPackage == null
14642 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14647 pw.println(" mHomeProcess: " + mHomeProcess);
14649 if (mPreviousProcess != null && (dumpPackage == null
14650 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14655 pw.println(" mPreviousProcess: " + mPreviousProcess);
14658 StringBuilder sb = new StringBuilder(128);
14659 sb.append(" mPreviousProcessVisibleTime: ");
14660 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14663 if (mHeavyWeightProcess != null && (dumpPackage == null
14664 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14669 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14671 if (dumpPackage == null) {
14672 pw.println(" mConfiguration: " + mConfiguration);
14675 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14676 if (mCompatModePackages.getPackages().size() > 0) {
14677 boolean printed = false;
14678 for (Map.Entry<String, Integer> entry
14679 : mCompatModePackages.getPackages().entrySet()) {
14680 String pkg = entry.getKey();
14681 int mode = entry.getValue();
14682 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14686 pw.println(" mScreenCompatPackages:");
14689 pw.print(" "); pw.print(pkg); pw.print(": ");
14690 pw.print(mode); pw.println();
14694 if (dumpPackage == null) {
14695 pw.println(" mWakefulness="
14696 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14697 pw.println(" mSleepTokens=" + mSleepTokens);
14698 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14699 + lockScreenShownToString());
14700 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14701 if (mRunningVoice != null) {
14702 pw.println(" mRunningVoice=" + mRunningVoice);
14703 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14706 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14707 || mOrigWaitForDebugger) {
14708 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14709 || dumpPackage.equals(mOrigDebugApp)) {
14714 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14715 + " mDebugTransient=" + mDebugTransient
14716 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14719 if (mCurAppTimeTracker != null) {
14720 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14722 if (mMemWatchProcesses.getMap().size() > 0) {
14723 pw.println(" Mem watch processes:");
14724 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14725 = mMemWatchProcesses.getMap();
14726 for (int i=0; i<procs.size(); i++) {
14727 final String proc = procs.keyAt(i);
14728 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14729 for (int j=0; j<uids.size(); j++) {
14734 StringBuilder sb = new StringBuilder();
14735 sb.append(" ").append(proc).append('/');
14736 UserHandle.formatUid(sb, uids.keyAt(j));
14737 Pair<Long, String> val = uids.valueAt(j);
14738 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14739 if (val.second != null) {
14740 sb.append(", report to ").append(val.second);
14742 pw.println(sb.toString());
14745 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14746 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14747 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14748 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14750 if (mTrackAllocationApp != null) {
14751 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14756 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14759 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14760 || mProfileFd != null) {
14761 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14766 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14767 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14768 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14769 + mAutoStopProfiler);
14770 pw.println(" mProfileType=" + mProfileType);
14773 if (mNativeDebuggingApp != null) {
14774 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14779 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14782 if (dumpPackage == null) {
14783 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14784 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14785 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14787 if (mController != null) {
14788 pw.println(" mController=" + mController
14789 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14792 pw.println(" Total persistent processes: " + numPers);
14793 pw.println(" mProcessesReady=" + mProcessesReady
14794 + " mSystemReady=" + mSystemReady
14795 + " mBooted=" + mBooted
14796 + " mFactoryTest=" + mFactoryTest);
14797 pw.println(" mBooting=" + mBooting
14798 + " mCallFinishBooting=" + mCallFinishBooting
14799 + " mBootAnimationComplete=" + mBootAnimationComplete);
14800 pw.print(" mLastPowerCheckRealtime=");
14801 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14803 pw.print(" mLastPowerCheckUptime=");
14804 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14806 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14807 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14808 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14809 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
14810 + " (" + mLruProcesses.size() + " total)"
14811 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14812 + " mNumServiceProcs=" + mNumServiceProcs
14813 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14814 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
14815 + " mLastMemoryLevel=" + mLastMemoryLevel
14816 + " mLastNumProcesses=" + mLastNumProcesses);
14817 long now = SystemClock.uptimeMillis();
14818 pw.print(" mLastIdleTime=");
14819 TimeUtils.formatDuration(now, mLastIdleTime, pw);
14820 pw.print(" mLowRamSinceLastIdle=");
14821 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14826 if (!printedAnything) {
14827 pw.println(" (nothing)");
14831 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14832 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14833 if (mProcessesToGc.size() > 0) {
14834 boolean printed = false;
14835 long now = SystemClock.uptimeMillis();
14836 for (int i=0; i<mProcessesToGc.size(); i++) {
14837 ProcessRecord proc = mProcessesToGc.get(i);
14838 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14842 if (needSep) pw.println();
14844 pw.println(" Processes that are waiting to GC:");
14847 pw.print(" Process "); pw.println(proc);
14848 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
14849 pw.print(", last gced=");
14850 pw.print(now-proc.lastRequestedGc);
14851 pw.print(" ms ago, last lowMem=");
14852 pw.print(now-proc.lastLowMemory);
14853 pw.println(" ms ago");
14860 void printOomLevel(PrintWriter pw, String name, int adj) {
14864 if (adj < 10) pw.print(' ');
14866 if (adj > -10) pw.print(' ');
14872 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14876 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14877 int opti, boolean dumpAll) {
14878 boolean needSep = false;
14880 if (mLruProcesses.size() > 0) {
14881 if (needSep) pw.println();
14883 pw.println(" OOM levels:");
14884 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14885 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14886 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14887 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14888 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14889 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14890 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14891 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14892 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14893 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14894 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14895 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14896 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14897 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14899 if (needSep) pw.println();
14900 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
14901 pw.print(" total, non-act at ");
14902 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14903 pw.print(", non-svc at ");
14904 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14906 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
14910 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14913 pw.println(" mHomeProcess: " + mHomeProcess);
14914 pw.println(" mPreviousProcess: " + mPreviousProcess);
14915 if (mHeavyWeightProcess != null) {
14916 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14923 * There are three ways to call this:
14924 * - no provider specified: dump all the providers
14925 * - a flattened component name that matched an existing provider was specified as the
14926 * first arg: dump that one provider
14927 * - the first arg isn't the flattened component name of an existing provider:
14928 * dump all providers whose component contains the first arg as a substring
14930 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14931 int opti, boolean dumpAll) {
14932 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14935 static class ItemMatcher {
14936 ArrayList<ComponentName> components;
14937 ArrayList<String> strings;
14938 ArrayList<Integer> objects;
14945 void build(String name) {
14946 ComponentName componentName = ComponentName.unflattenFromString(name);
14947 if (componentName != null) {
14948 if (components == null) {
14949 components = new ArrayList<ComponentName>();
14951 components.add(componentName);
14955 // Not a '/' separated full component name; maybe an object ID?
14957 objectId = Integer.parseInt(name, 16);
14958 if (objects == null) {
14959 objects = new ArrayList<Integer>();
14961 objects.add(objectId);
14963 } catch (RuntimeException e) {
14964 // Not an integer; just do string match.
14965 if (strings == null) {
14966 strings = new ArrayList<String>();
14974 int build(String[] args, int opti) {
14975 for (; opti<args.length; opti++) {
14976 String name = args[opti];
14977 if ("--".equals(name)) {
14985 boolean match(Object object, ComponentName comp) {
14989 if (components != null) {
14990 for (int i=0; i<components.size(); i++) {
14991 if (components.get(i).equals(comp)) {
14996 if (objects != null) {
14997 for (int i=0; i<objects.size(); i++) {
14998 if (System.identityHashCode(object) == objects.get(i)) {
15003 if (strings != null) {
15004 String flat = comp.flattenToString();
15005 for (int i=0; i<strings.size(); i++) {
15006 if (flat.contains(strings.get(i))) {
15016 * There are three things that cmd can be:
15017 * - a flattened component name that matches an existing activity
15018 * - the cmd arg isn't the flattened component name of an existing activity:
15019 * dump all activity whose component contains the cmd as a substring
15020 * - A hex number of the ActivityRecord object instance.
15022 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15023 int opti, boolean dumpAll) {
15024 ArrayList<ActivityRecord> activities;
15026 synchronized (this) {
15027 activities = mStackSupervisor.getDumpActivitiesLocked(name);
15030 if (activities.size() <= 0) {
15034 String[] newArgs = new String[args.length - opti];
15035 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15037 TaskRecord lastTask = null;
15038 boolean needSep = false;
15039 for (int i=activities.size()-1; i>=0; i--) {
15040 ActivityRecord r = activities.get(i);
15045 synchronized (this) {
15046 if (lastTask != r.task) {
15048 pw.print("TASK "); pw.print(lastTask.affinity);
15049 pw.print(" id="); pw.println(lastTask.taskId);
15051 lastTask.dump(pw, " ");
15055 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
15061 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15062 * there is a thread associated with the activity.
15064 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15065 final ActivityRecord r, String[] args, boolean dumpAll) {
15066 String innerPrefix = prefix + " ";
15067 synchronized (this) {
15068 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15069 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15071 if (r.app != null) pw.println(r.app.pid);
15072 else pw.println("(not running)");
15074 r.dump(pw, innerPrefix);
15077 if (r.app != null && r.app.thread != null) {
15078 // flush anything that is already in the PrintWriter since the thread is going
15079 // to write to the file descriptor directly
15082 TransferPipe tp = new TransferPipe();
15084 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15085 r.appToken, innerPrefix, args);
15090 } catch (IOException e) {
15091 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15092 } catch (RemoteException e) {
15093 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15098 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15099 int opti, boolean dumpAll, String dumpPackage) {
15100 boolean needSep = false;
15101 boolean onlyHistory = false;
15102 boolean printedAnything = false;
15104 if ("history".equals(dumpPackage)) {
15105 if (opti < args.length && "-s".equals(args[opti])) {
15108 onlyHistory = true;
15109 dumpPackage = null;
15112 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15113 if (!onlyHistory && dumpAll) {
15114 if (mRegisteredReceivers.size() > 0) {
15115 boolean printed = false;
15116 Iterator it = mRegisteredReceivers.values().iterator();
15117 while (it.hasNext()) {
15118 ReceiverList r = (ReceiverList)it.next();
15119 if (dumpPackage != null && (r.app == null ||
15120 !dumpPackage.equals(r.app.info.packageName))) {
15124 pw.println(" Registered Receivers:");
15127 printedAnything = true;
15129 pw.print(" * "); pw.println(r);
15134 if (mReceiverResolver.dump(pw, needSep ?
15135 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
15136 " ", dumpPackage, false, false)) {
15138 printedAnything = true;
15142 for (BroadcastQueue q : mBroadcastQueues) {
15143 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15144 printedAnything |= needSep;
15149 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15150 for (int user=0; user<mStickyBroadcasts.size(); user++) {
15155 printedAnything = true;
15156 pw.print(" Sticky broadcasts for user ");
15157 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15158 StringBuilder sb = new StringBuilder(128);
15159 for (Map.Entry<String, ArrayList<Intent>> ent
15160 : mStickyBroadcasts.valueAt(user).entrySet()) {
15161 pw.print(" * Sticky action "); pw.print(ent.getKey());
15164 ArrayList<Intent> intents = ent.getValue();
15165 final int N = intents.size();
15166 for (int i=0; i<N; i++) {
15168 sb.append(" Intent: ");
15169 intents.get(i).toShortString(sb, false, true, false, false);
15170 pw.println(sb.toString());
15171 Bundle bundle = intents.get(i).getExtras();
15172 if (bundle != null) {
15174 pw.println(bundle.toString());
15184 if (!onlyHistory && dumpAll) {
15186 for (BroadcastQueue queue : mBroadcastQueues) {
15187 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
15188 + queue.mBroadcastsScheduled);
15190 pw.println(" mHandler:");
15191 mHandler.dump(new PrintWriterPrinter(pw), " ");
15193 printedAnything = true;
15196 if (!printedAnything) {
15197 pw.println(" (nothing)");
15201 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15202 int opti, boolean dumpAll, String dumpPackage) {
15203 if (mCurBroadcastStats == null) {
15207 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15208 final long now = SystemClock.elapsedRealtime();
15209 if (mLastBroadcastStats != null) {
15210 pw.print(" Last stats (from ");
15211 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15213 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15215 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15216 - mLastBroadcastStats.mStartUptime, pw);
15217 pw.println(" uptime):");
15218 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15219 pw.println(" (nothing)");
15223 pw.print(" Current stats (from ");
15224 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15225 pw.print(" to now, ");
15226 TimeUtils.formatDuration(SystemClock.uptimeMillis()
15227 - mCurBroadcastStats.mStartUptime, pw);
15228 pw.println(" uptime):");
15229 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15230 pw.println(" (nothing)");
15234 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15235 int opti, boolean fullCheckin, String dumpPackage) {
15236 if (mCurBroadcastStats == null) {
15240 if (mLastBroadcastStats != null) {
15241 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15243 mLastBroadcastStats = null;
15247 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15249 mCurBroadcastStats = null;
15253 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15254 int opti, boolean dumpAll, String dumpPackage) {
15256 boolean printedAnything = false;
15258 ItemMatcher matcher = new ItemMatcher();
15259 matcher.build(args, opti);
15261 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15263 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15264 printedAnything |= needSep;
15266 if (mLaunchingProviders.size() > 0) {
15267 boolean printed = false;
15268 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15269 ContentProviderRecord r = mLaunchingProviders.get(i);
15270 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15274 if (needSep) pw.println();
15276 pw.println(" Launching content providers:");
15278 printedAnything = true;
15280 pw.print(" Launching #"); pw.print(i); pw.print(": ");
15285 if (!printedAnything) {
15286 pw.println(" (nothing)");
15290 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15291 int opti, boolean dumpAll, String dumpPackage) {
15292 boolean needSep = false;
15293 boolean printedAnything = false;
15295 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15297 if (mGrantedUriPermissions.size() > 0) {
15298 boolean printed = false;
15300 if (dumpPackage != null) {
15302 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15303 MATCH_UNINSTALLED_PACKAGES, 0);
15304 } catch (NameNotFoundException e) {
15308 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15309 int uid = mGrantedUriPermissions.keyAt(i);
15310 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15313 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15315 if (needSep) pw.println();
15317 pw.println(" Granted Uri Permissions:");
15319 printedAnything = true;
15321 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
15322 for (UriPermission perm : perms.values()) {
15323 pw.print(" "); pw.println(perm);
15325 perm.dump(pw, " ");
15331 if (!printedAnything) {
15332 pw.println(" (nothing)");
15336 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15337 int opti, boolean dumpAll, String dumpPackage) {
15338 boolean printed = false;
15340 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15342 if (mIntentSenderRecords.size() > 0) {
15343 Iterator<WeakReference<PendingIntentRecord>> it
15344 = mIntentSenderRecords.values().iterator();
15345 while (it.hasNext()) {
15346 WeakReference<PendingIntentRecord> ref = it.next();
15347 PendingIntentRecord rec = ref != null ? ref.get(): null;
15348 if (dumpPackage != null && (rec == null
15349 || !dumpPackage.equals(rec.key.packageName))) {
15354 pw.print(" * "); pw.println(rec);
15359 pw.print(" * "); pw.println(ref);
15365 pw.println(" (nothing)");
15369 private static final int dumpProcessList(PrintWriter pw,
15370 ActivityManagerService service, List list,
15371 String prefix, String normalLabel, String persistentLabel,
15372 String dumpPackage) {
15374 final int N = list.size()-1;
15375 for (int i=N; i>=0; i--) {
15376 ProcessRecord r = (ProcessRecord)list.get(i);
15377 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15380 pw.println(String.format("%s%s #%2d: %s",
15381 prefix, (r.persistent ? persistentLabel : normalLabel),
15383 if (r.persistent) {
15390 private static final boolean dumpProcessOomList(PrintWriter pw,
15391 ActivityManagerService service, List<ProcessRecord> origList,
15392 String prefix, String normalLabel, String persistentLabel,
15393 boolean inclDetails, String dumpPackage) {
15395 ArrayList<Pair<ProcessRecord, Integer>> list
15396 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15397 for (int i=0; i<origList.size(); i++) {
15398 ProcessRecord r = origList.get(i);
15399 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15402 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15405 if (list.size() <= 0) {
15409 Comparator<Pair<ProcessRecord, Integer>> comparator
15410 = new Comparator<Pair<ProcessRecord, Integer>>() {
15412 public int compare(Pair<ProcessRecord, Integer> object1,
15413 Pair<ProcessRecord, Integer> object2) {
15414 if (object1.first.setAdj != object2.first.setAdj) {
15415 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15417 if (object1.first.setProcState != object2.first.setProcState) {
15418 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15420 if (object1.second.intValue() != object2.second.intValue()) {
15421 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15427 Collections.sort(list, comparator);
15429 final long curRealtime = SystemClock.elapsedRealtime();
15430 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15431 final long curUptime = SystemClock.uptimeMillis();
15432 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15434 for (int i=list.size()-1; i>=0; i--) {
15435 ProcessRecord r = list.get(i).first;
15436 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15438 switch (r.setSchedGroup) {
15439 case ProcessList.SCHED_GROUP_BACKGROUND:
15442 case ProcessList.SCHED_GROUP_DEFAULT:
15445 case ProcessList.SCHED_GROUP_TOP_APP:
15453 if (r.foregroundActivities) {
15455 } else if (r.foregroundServices) {
15460 String procState = ProcessList.makeProcStateString(r.curProcState);
15462 pw.print(r.persistent ? persistentLabel : normalLabel);
15464 int num = (origList.size()-1)-list.get(i).second;
15465 if (num < 10) pw.print(' ');
15470 pw.print(schedGroup);
15472 pw.print(foreground);
15474 pw.print(procState);
15476 if (r.trimMemoryLevel < 10) pw.print(' ');
15477 pw.print(r.trimMemoryLevel);
15479 pw.print(r.toShortString());
15481 pw.print(r.adjType);
15483 if (r.adjSource != null || r.adjTarget != null) {
15486 if (r.adjTarget instanceof ComponentName) {
15487 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15488 } else if (r.adjTarget != null) {
15489 pw.print(r.adjTarget.toString());
15491 pw.print("{null}");
15494 if (r.adjSource instanceof ProcessRecord) {
15496 pw.print(((ProcessRecord)r.adjSource).toShortString());
15498 } else if (r.adjSource != null) {
15499 pw.println(r.adjSource.toString());
15501 pw.println("{null}");
15507 pw.print("oom: max="); pw.print(r.maxAdj);
15508 pw.print(" curRaw="); pw.print(r.curRawAdj);
15509 pw.print(" setRaw="); pw.print(r.setRawAdj);
15510 pw.print(" cur="); pw.print(r.curAdj);
15511 pw.print(" set="); pw.println(r.setAdj);
15514 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15515 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15516 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15517 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15518 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15522 pw.print("cached="); pw.print(r.cached);
15523 pw.print(" empty="); pw.print(r.empty);
15524 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15526 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15527 if (r.lastWakeTime != 0) {
15529 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15530 synchronized (stats) {
15531 wtime = stats.getProcessWakeTime(r.info.uid,
15532 r.pid, curRealtime);
15534 long timeUsed = wtime - r.lastWakeTime;
15537 pw.print("keep awake over ");
15538 TimeUtils.formatDuration(realtimeSince, pw);
15539 pw.print(" used ");
15540 TimeUtils.formatDuration(timeUsed, pw);
15542 pw.print((timeUsed*100)/realtimeSince);
15545 if (r.lastCpuTime != 0) {
15546 long timeUsed = r.curCpuTime - r.lastCpuTime;
15549 pw.print("run cpu over ");
15550 TimeUtils.formatDuration(uptimeSince, pw);
15551 pw.print(" used ");
15552 TimeUtils.formatDuration(timeUsed, pw);
15554 pw.print((timeUsed*100)/uptimeSince);
15563 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15565 ArrayList<ProcessRecord> procs;
15566 synchronized (this) {
15567 if (args != null && args.length > start
15568 && args[start].charAt(0) != '-') {
15569 procs = new ArrayList<ProcessRecord>();
15572 pid = Integer.parseInt(args[start]);
15573 } catch (NumberFormatException e) {
15575 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15576 ProcessRecord proc = mLruProcesses.get(i);
15577 if (proc.pid == pid) {
15579 } else if (allPkgs && proc.pkgList != null
15580 && proc.pkgList.containsKey(args[start])) {
15582 } else if (proc.processName.equals(args[start])) {
15586 if (procs.size() <= 0) {
15590 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15596 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15597 PrintWriter pw, String[] args) {
15598 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15599 if (procs == null) {
15600 pw.println("No process found for: " + args[0]);
15604 long uptime = SystemClock.uptimeMillis();
15605 long realtime = SystemClock.elapsedRealtime();
15606 pw.println("Applications Graphics Acceleration Info:");
15607 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15609 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15610 ProcessRecord r = procs.get(i);
15611 if (r.thread != null) {
15612 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15615 TransferPipe tp = new TransferPipe();
15617 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15622 } catch (IOException e) {
15623 pw.println("Failure while dumping the app: " + r);
15625 } catch (RemoteException e) {
15626 pw.println("Got a RemoteException while dumping the app " + r);
15633 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15634 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15635 if (procs == null) {
15636 pw.println("No process found for: " + args[0]);
15640 pw.println("Applications Database Info:");
15642 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15643 ProcessRecord r = procs.get(i);
15644 if (r.thread != null) {
15645 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15648 TransferPipe tp = new TransferPipe();
15650 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15655 } catch (IOException e) {
15656 pw.println("Failure while dumping the app: " + r);
15658 } catch (RemoteException e) {
15659 pw.println("Got a RemoteException while dumping the app " + r);
15666 final static class MemItem {
15667 final boolean isProc;
15668 final String label;
15669 final String shortLabel;
15671 final long swapPss;
15673 final boolean hasActivities;
15674 ArrayList<MemItem> subitems;
15676 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15677 boolean _hasActivities) {
15680 shortLabel = _shortLabel;
15682 swapPss = _swapPss;
15684 hasActivities = _hasActivities;
15687 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15690 shortLabel = _shortLabel;
15692 swapPss = _swapPss;
15694 hasActivities = false;
15698 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15699 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15700 if (sort && !isCompact) {
15701 Collections.sort(items, new Comparator<MemItem>() {
15703 public int compare(MemItem lhs, MemItem rhs) {
15704 if (lhs.pss < rhs.pss) {
15706 } else if (lhs.pss > rhs.pss) {
15714 for (int i=0; i<items.size(); i++) {
15715 MemItem mi = items.get(i);
15718 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15719 mi.label, stringifyKBSize(mi.swapPss));
15721 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15723 } else if (mi.isProc) {
15724 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15725 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15726 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15727 pw.println(mi.hasActivities ? ",a" : ",e");
15729 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15730 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15732 if (mi.subitems != null) {
15733 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15734 true, isCompact, dumpSwapPss);
15739 // These are in KB.
15740 static final long[] DUMP_MEM_BUCKETS = new long[] {
15741 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15742 120*1024, 160*1024, 200*1024,
15743 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15744 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15747 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15748 boolean stackLike) {
15749 int start = label.lastIndexOf('.');
15750 if (start >= 0) start++;
15752 int end = label.length();
15753 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15754 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15755 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15756 out.append(bucket);
15757 out.append(stackLike ? "MB." : "MB ");
15758 out.append(label, start, end);
15762 out.append(memKB/1024);
15763 out.append(stackLike ? "MB." : "MB ");
15764 out.append(label, start, end);
15767 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15768 ProcessList.NATIVE_ADJ,
15769 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15770 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15771 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15772 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15773 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15774 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15776 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15778 "System", "Persistent", "Persistent Service", "Foreground",
15779 "Visible", "Perceptible",
15780 "Heavy Weight", "Backup",
15781 "A Services", "Home",
15782 "Previous", "B Services", "Cached"
15784 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15786 "sys", "pers", "persvc", "fore",
15789 "servicea", "home",
15790 "prev", "serviceb", "cached"
15793 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15794 long realtime, boolean isCheckinRequest, boolean isCompact) {
15796 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15798 if (isCheckinRequest || isCompact) {
15799 // short checkin version
15800 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15802 pw.println("Applications Memory Usage (in Kilobytes):");
15803 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15807 private static final int KSM_SHARED = 0;
15808 private static final int KSM_SHARING = 1;
15809 private static final int KSM_UNSHARED = 2;
15810 private static final int KSM_VOLATILE = 3;
15812 private final long[] getKsmInfo() {
15813 long[] longOut = new long[4];
15814 final int[] SINGLE_LONG_FORMAT = new int[] {
15815 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15817 long[] longTmp = new long[1];
15818 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15819 SINGLE_LONG_FORMAT, null, longTmp, null);
15820 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15822 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15823 SINGLE_LONG_FORMAT, null, longTmp, null);
15824 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15826 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15827 SINGLE_LONG_FORMAT, null, longTmp, null);
15828 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15830 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15831 SINGLE_LONG_FORMAT, null, longTmp, null);
15832 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15836 private static String stringifySize(long size, int order) {
15837 Locale locale = Locale.US;
15840 return String.format(locale, "%,13d", size);
15842 return String.format(locale, "%,9dK", size / 1024);
15844 return String.format(locale, "%,5dM", size / 1024 / 1024);
15845 case 1024 * 1024 * 1024:
15846 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15848 throw new IllegalArgumentException("Invalid size order");
15852 private static String stringifyKBSize(long size) {
15853 return stringifySize(size * 1024, 1024);
15856 // Update this version number in case you change the 'compact' format
15857 private static final int MEMINFO_COMPACT_VERSION = 1;
15859 final void dumpApplicationMemoryUsage(FileDescriptor fd,
15860 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15861 boolean dumpDetails = false;
15862 boolean dumpFullDetails = false;
15863 boolean dumpDalvik = false;
15864 boolean dumpSummaryOnly = false;
15865 boolean dumpUnreachable = false;
15866 boolean oomOnly = false;
15867 boolean isCompact = false;
15868 boolean localOnly = false;
15869 boolean packages = false;
15870 boolean isCheckinRequest = false;
15871 boolean dumpSwapPss = false;
15874 while (opti < args.length) {
15875 String opt = args[opti];
15876 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15880 if ("-a".equals(opt)) {
15881 dumpDetails = true;
15882 dumpFullDetails = true;
15884 dumpSwapPss = true;
15885 } else if ("-d".equals(opt)) {
15887 } else if ("-c".equals(opt)) {
15889 } else if ("-s".equals(opt)) {
15890 dumpDetails = true;
15891 dumpSummaryOnly = true;
15892 } else if ("-S".equals(opt)) {
15893 dumpSwapPss = true;
15894 } else if ("--unreachable".equals(opt)) {
15895 dumpUnreachable = true;
15896 } else if ("--oom".equals(opt)) {
15898 } else if ("--local".equals(opt)) {
15900 } else if ("--package".equals(opt)) {
15902 } else if ("--checkin".equals(opt)) {
15903 isCheckinRequest = true;
15905 } else if ("-h".equals(opt)) {
15906 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15907 pw.println(" -a: include all available information for each process.");
15908 pw.println(" -d: include dalvik details.");
15909 pw.println(" -c: dump in a compact machine-parseable representation.");
15910 pw.println(" -s: dump only summary of application memory usage.");
15911 pw.println(" -S: dump also SwapPss.");
15912 pw.println(" --oom: only show processes organized by oom adj.");
15913 pw.println(" --local: only collect details locally, don't call process.");
15914 pw.println(" --package: interpret process arg as package, dumping all");
15915 pw.println(" processes that have loaded that package.");
15916 pw.println(" --checkin: dump data for a checkin");
15917 pw.println("If [process] is specified it can be the name or ");
15918 pw.println("pid of a specific process to dump.");
15921 pw.println("Unknown argument: " + opt + "; use -h for help");
15925 long uptime = SystemClock.uptimeMillis();
15926 long realtime = SystemClock.elapsedRealtime();
15927 final long[] tmpLong = new long[1];
15929 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15930 if (procs == null) {
15931 // No Java processes. Maybe they want to print a native process.
15932 if (args != null && args.length > opti
15933 && args[opti].charAt(0) != '-') {
15934 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15935 = new ArrayList<ProcessCpuTracker.Stats>();
15936 updateCpuStatsNow();
15939 findPid = Integer.parseInt(args[opti]);
15940 } catch (NumberFormatException e) {
15942 synchronized (mProcessCpuTracker) {
15943 final int N = mProcessCpuTracker.countStats();
15944 for (int i=0; i<N; i++) {
15945 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15946 if (st.pid == findPid || (st.baseName != null
15947 && st.baseName.equals(args[opti]))) {
15948 nativeProcs.add(st);
15952 if (nativeProcs.size() > 0) {
15953 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15955 Debug.MemoryInfo mi = null;
15956 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15957 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15958 final int pid = r.pid;
15959 if (!isCheckinRequest && dumpDetails) {
15960 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15963 mi = new Debug.MemoryInfo();
15965 if (dumpDetails || (!brief && !oomOnly)) {
15966 Debug.getMemoryInfo(pid, mi);
15968 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15969 mi.dalvikPrivateDirty = (int)tmpLong[0];
15971 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15972 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15973 if (isCheckinRequest) {
15980 pw.println("No process found for: " + args[opti]);
15984 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15985 dumpDetails = true;
15988 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15990 String[] innerArgs = new String[args.length-opti];
15991 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15993 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15994 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15995 long nativePss = 0;
15996 long nativeSwapPss = 0;
15997 long dalvikPss = 0;
15998 long dalvikSwapPss = 0;
15999 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16001 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16004 long otherSwapPss = 0;
16005 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16006 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16008 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16009 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16010 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16011 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16014 long totalSwapPss = 0;
16015 long cachedPss = 0;
16016 long cachedSwapPss = 0;
16017 boolean hasSwapPss = false;
16019 Debug.MemoryInfo mi = null;
16020 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16021 final ProcessRecord r = procs.get(i);
16022 final IApplicationThread thread;
16025 final boolean hasActivities;
16026 synchronized (this) {
16029 oomAdj = r.getSetAdjWithServices();
16030 hasActivities = r.activities.size() > 0;
16032 if (thread != null) {
16033 if (!isCheckinRequest && dumpDetails) {
16034 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16037 mi = new Debug.MemoryInfo();
16039 if (dumpDetails || (!brief && !oomOnly)) {
16040 Debug.getMemoryInfo(pid, mi);
16041 hasSwapPss = mi.hasSwappedOutPss;
16043 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16044 mi.dalvikPrivateDirty = (int)tmpLong[0];
16048 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16049 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16050 if (isCheckinRequest) {
16056 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16057 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16058 } catch (RemoteException e) {
16059 if (!isCheckinRequest) {
16060 pw.println("Got RemoteException!");
16067 final long myTotalPss = mi.getTotalPss();
16068 final long myTotalUss = mi.getTotalUss();
16069 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16071 synchronized (this) {
16072 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16073 // Record this for posterity if the process has been stable.
16074 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16078 if (!isCheckinRequest && mi != null) {
16079 totalPss += myTotalPss;
16080 totalSwapPss += myTotalSwapPss;
16081 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16082 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16083 myTotalSwapPss, pid, hasActivities);
16084 procMems.add(pssItem);
16085 procMemsMap.put(pid, pssItem);
16087 nativePss += mi.nativePss;
16088 nativeSwapPss += mi.nativeSwappedOutPss;
16089 dalvikPss += mi.dalvikPss;
16090 dalvikSwapPss += mi.dalvikSwappedOutPss;
16091 for (int j=0; j<dalvikSubitemPss.length; j++) {
16092 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16093 dalvikSubitemSwapPss[j] +=
16094 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16096 otherPss += mi.otherPss;
16097 otherSwapPss += mi.otherSwappedOutPss;
16098 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16099 long mem = mi.getOtherPss(j);
16102 mem = mi.getOtherSwappedOutPss(j);
16103 miscSwapPss[j] += mem;
16104 otherSwapPss -= mem;
16107 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16108 cachedPss += myTotalPss;
16109 cachedSwapPss += myTotalSwapPss;
16112 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16113 if (oomIndex == (oomPss.length - 1)
16114 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16115 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16116 oomPss[oomIndex] += myTotalPss;
16117 oomSwapPss[oomIndex] += myTotalSwapPss;
16118 if (oomProcs[oomIndex] == null) {
16119 oomProcs[oomIndex] = new ArrayList<MemItem>();
16121 oomProcs[oomIndex].add(pssItem);
16129 long nativeProcTotalPss = 0;
16131 if (!isCheckinRequest && procs.size() > 1 && !packages) {
16132 // If we are showing aggregations, also look for native processes to
16133 // include so that our aggregations are more accurate.
16134 updateCpuStatsNow();
16136 synchronized (mProcessCpuTracker) {
16137 final int N = mProcessCpuTracker.countStats();
16138 for (int i=0; i<N; i++) {
16139 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16140 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16142 mi = new Debug.MemoryInfo();
16144 if (!brief && !oomOnly) {
16145 Debug.getMemoryInfo(st.pid, mi);
16147 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16148 mi.nativePrivateDirty = (int)tmpLong[0];
16151 final long myTotalPss = mi.getTotalPss();
16152 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16153 totalPss += myTotalPss;
16154 nativeProcTotalPss += myTotalPss;
16156 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16157 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16158 procMems.add(pssItem);
16160 nativePss += mi.nativePss;
16161 nativeSwapPss += mi.nativeSwappedOutPss;
16162 dalvikPss += mi.dalvikPss;
16163 dalvikSwapPss += mi.dalvikSwappedOutPss;
16164 for (int j=0; j<dalvikSubitemPss.length; j++) {
16165 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16166 dalvikSubitemSwapPss[j] +=
16167 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16169 otherPss += mi.otherPss;
16170 otherSwapPss += mi.otherSwappedOutPss;
16171 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16172 long mem = mi.getOtherPss(j);
16175 mem = mi.getOtherSwappedOutPss(j);
16176 miscSwapPss[j] += mem;
16177 otherSwapPss -= mem;
16179 oomPss[0] += myTotalPss;
16180 oomSwapPss[0] += myTotalSwapPss;
16181 if (oomProcs[0] == null) {
16182 oomProcs[0] = new ArrayList<MemItem>();
16184 oomProcs[0].add(pssItem);
16189 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16191 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16192 final MemItem dalvikItem =
16193 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16194 if (dalvikSubitemPss.length > 0) {
16195 dalvikItem.subitems = new ArrayList<MemItem>();
16196 for (int j=0; j<dalvikSubitemPss.length; j++) {
16197 final String name = Debug.MemoryInfo.getOtherLabel(
16198 Debug.MemoryInfo.NUM_OTHER_STATS + j);
16199 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16200 dalvikSubitemSwapPss[j], j));
16203 catMems.add(dalvikItem);
16204 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16205 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16206 String label = Debug.MemoryInfo.getOtherLabel(j);
16207 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16210 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16211 for (int j=0; j<oomPss.length; j++) {
16212 if (oomPss[j] != 0) {
16213 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16214 : DUMP_MEM_OOM_LABEL[j];
16215 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16216 DUMP_MEM_OOM_ADJ[j]);
16217 item.subitems = oomProcs[j];
16222 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16223 if (!brief && !oomOnly && !isCompact) {
16225 pw.println("Total PSS by process:");
16226 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
16230 pw.println("Total PSS by OOM adjustment:");
16232 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
16233 if (!brief && !oomOnly) {
16234 PrintWriter out = categoryPw != null ? categoryPw : pw;
16237 out.println("Total PSS by category:");
16239 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
16244 MemInfoReader memInfo = new MemInfoReader();
16245 memInfo.readMemInfo();
16246 if (nativeProcTotalPss > 0) {
16247 synchronized (this) {
16248 final long cachedKb = memInfo.getCachedSizeKb();
16249 final long freeKb = memInfo.getFreeSizeKb();
16250 final long zramKb = memInfo.getZramTotalSizeKb();
16251 final long kernelKb = memInfo.getKernelUsedSizeKb();
16252 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16253 kernelKb*1024, nativeProcTotalPss*1024);
16254 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16255 nativeProcTotalPss);
16260 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16261 pw.print(" (status ");
16262 switch (mLastMemoryLevel) {
16263 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16264 pw.println("normal)");
16266 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16267 pw.println("moderate)");
16269 case ProcessStats.ADJ_MEM_FACTOR_LOW:
16270 pw.println("low)");
16272 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16273 pw.println("critical)");
16276 pw.print(mLastMemoryLevel);
16280 pw.print(" Free RAM: ");
16281 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16282 + memInfo.getFreeSizeKb()));
16284 pw.print(stringifyKBSize(cachedPss));
16285 pw.print(" cached pss + ");
16286 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16287 pw.print(" cached kernel + ");
16288 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16289 pw.println(" free)");
16291 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16292 pw.print(cachedPss + memInfo.getCachedSizeKb()
16293 + memInfo.getFreeSizeKb()); pw.print(",");
16294 pw.println(totalPss - cachedPss);
16297 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16298 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16299 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16301 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16302 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16303 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16304 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16305 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16307 pw.print("lostram,"); pw.println(lostRAM);
16310 if (memInfo.getZramTotalSizeKb() != 0) {
16312 pw.print(" ZRAM: ");
16313 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16314 pw.print(" physical used for ");
16315 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16316 - memInfo.getSwapFreeSizeKb()));
16317 pw.print(" in swap (");
16318 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16319 pw.println(" total swap)");
16321 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16322 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16323 pw.println(memInfo.getSwapFreeSizeKb());
16326 final long[] ksm = getKsmInfo();
16328 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16329 || ksm[KSM_VOLATILE] != 0) {
16330 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16331 pw.print(" saved from shared ");
16332 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16333 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16334 pw.print(" unshared; ");
16335 pw.print(stringifyKBSize(
16336 ksm[KSM_VOLATILE])); pw.println(" volatile");
16338 pw.print(" Tuning: ");
16339 pw.print(ActivityManager.staticGetMemoryClass());
16340 pw.print(" (large ");
16341 pw.print(ActivityManager.staticGetLargeMemoryClass());
16342 pw.print("), oom ");
16343 pw.print(stringifySize(
16344 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16345 pw.print(", restore limit ");
16346 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16347 if (ActivityManager.isLowRamDeviceStatic()) {
16348 pw.print(" (low-ram)");
16350 if (ActivityManager.isHighEndGfx()) {
16351 pw.print(" (high-end-gfx)");
16355 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16356 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16357 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16358 pw.print("tuning,");
16359 pw.print(ActivityManager.staticGetMemoryClass());
16361 pw.print(ActivityManager.staticGetLargeMemoryClass());
16363 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16364 if (ActivityManager.isLowRamDeviceStatic()) {
16365 pw.print(",low-ram");
16367 if (ActivityManager.isHighEndGfx()) {
16368 pw.print(",high-end-gfx");
16376 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16377 long memtrack, String name) {
16379 sb.append(ProcessList.makeOomAdjString(oomAdj));
16381 sb.append(ProcessList.makeProcStateString(procState));
16383 ProcessList.appendRamKb(sb, pss);
16386 if (memtrack > 0) {
16388 sb.append(stringifyKBSize(memtrack));
16389 sb.append(" memtrack)");
16393 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16394 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16395 sb.append(" (pid ");
16398 sb.append(mi.adjType);
16400 if (mi.adjReason != null) {
16402 sb.append(mi.adjReason);
16407 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16408 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16409 for (int i=0, N=memInfos.size(); i<N; i++) {
16410 ProcessMemInfo mi = memInfos.get(i);
16411 infoMap.put(mi.pid, mi);
16413 updateCpuStatsNow();
16414 long[] memtrackTmp = new long[1];
16415 synchronized (mProcessCpuTracker) {
16416 final int N = mProcessCpuTracker.countStats();
16417 for (int i=0; i<N; i++) {
16418 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16419 if (st.vsize > 0) {
16420 long pss = Debug.getPss(st.pid, null, memtrackTmp);
16422 if (infoMap.indexOfKey(st.pid) < 0) {
16423 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16424 ProcessList.NATIVE_ADJ, -1, "native", null);
16426 mi.memtrack = memtrackTmp[0];
16435 long totalMemtrack = 0;
16436 for (int i=0, N=memInfos.size(); i<N; i++) {
16437 ProcessMemInfo mi = memInfos.get(i);
16439 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16440 mi.memtrack = memtrackTmp[0];
16442 totalPss += mi.pss;
16443 totalMemtrack += mi.memtrack;
16445 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16446 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16447 if (lhs.oomAdj != rhs.oomAdj) {
16448 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16450 if (lhs.pss != rhs.pss) {
16451 return lhs.pss < rhs.pss ? 1 : -1;
16457 StringBuilder tag = new StringBuilder(128);
16458 StringBuilder stack = new StringBuilder(128);
16459 tag.append("Low on memory -- ");
16460 appendMemBucket(tag, totalPss, "total", false);
16461 appendMemBucket(stack, totalPss, "total", true);
16463 StringBuilder fullNativeBuilder = new StringBuilder(1024);
16464 StringBuilder shortNativeBuilder = new StringBuilder(1024);
16465 StringBuilder fullJavaBuilder = new StringBuilder(1024);
16467 boolean firstLine = true;
16468 int lastOomAdj = Integer.MIN_VALUE;
16469 long extraNativeRam = 0;
16470 long extraNativeMemtrack = 0;
16471 long cachedPss = 0;
16472 for (int i=0, N=memInfos.size(); i<N; i++) {
16473 ProcessMemInfo mi = memInfos.get(i);
16475 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16476 cachedPss += mi.pss;
16479 if (mi.oomAdj != ProcessList.NATIVE_ADJ
16480 && (mi.oomAdj < ProcessList.SERVICE_ADJ
16481 || mi.oomAdj == ProcessList.HOME_APP_ADJ
16482 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16483 if (lastOomAdj != mi.oomAdj) {
16484 lastOomAdj = mi.oomAdj;
16485 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16488 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16493 stack.append("\n\t at ");
16501 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16502 appendMemBucket(tag, mi.pss, mi.name, false);
16504 appendMemBucket(stack, mi.pss, mi.name, true);
16505 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16506 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16508 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16509 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16510 stack.append(DUMP_MEM_OOM_LABEL[k]);
16512 stack.append(DUMP_MEM_OOM_ADJ[k]);
16519 appendMemInfo(fullNativeBuilder, mi);
16520 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16521 // The short form only has native processes that are >= 512K.
16522 if (mi.pss >= 512) {
16523 appendMemInfo(shortNativeBuilder, mi);
16525 extraNativeRam += mi.pss;
16526 extraNativeMemtrack += mi.memtrack;
16529 // Short form has all other details, but if we have collected RAM
16530 // from smaller native processes let's dump a summary of that.
16531 if (extraNativeRam > 0) {
16532 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16533 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16534 shortNativeBuilder.append('\n');
16535 extraNativeRam = 0;
16537 appendMemInfo(fullJavaBuilder, mi);
16541 fullJavaBuilder.append(" ");
16542 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16543 fullJavaBuilder.append(": TOTAL");
16544 if (totalMemtrack > 0) {
16545 fullJavaBuilder.append(" (");
16546 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16547 fullJavaBuilder.append(" memtrack)");
16550 fullJavaBuilder.append("\n");
16552 MemInfoReader memInfo = new MemInfoReader();
16553 memInfo.readMemInfo();
16554 final long[] infos = memInfo.getRawInfo();
16556 StringBuilder memInfoBuilder = new StringBuilder(1024);
16557 Debug.getMemInfo(infos);
16558 memInfoBuilder.append(" MemInfo: ");
16559 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16560 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16561 memInfoBuilder.append(stringifyKBSize(
16562 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16563 memInfoBuilder.append(stringifyKBSize(
16564 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16565 memInfoBuilder.append(stringifyKBSize(
16566 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16567 memInfoBuilder.append(" ");
16568 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16569 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16570 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16571 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16572 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16573 memInfoBuilder.append(" ZRAM: ");
16574 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16575 memInfoBuilder.append(" RAM, ");
16576 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16577 memInfoBuilder.append(" swap total, ");
16578 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16579 memInfoBuilder.append(" swap free\n");
16581 final long[] ksm = getKsmInfo();
16582 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16583 || ksm[KSM_VOLATILE] != 0) {
16584 memInfoBuilder.append(" KSM: ");
16585 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16586 memInfoBuilder.append(" saved from shared ");
16587 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16588 memInfoBuilder.append("\n ");
16589 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16590 memInfoBuilder.append(" unshared; ");
16591 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16592 memInfoBuilder.append(" volatile\n");
16594 memInfoBuilder.append(" Free RAM: ");
16595 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16596 + memInfo.getFreeSizeKb()));
16597 memInfoBuilder.append("\n");
16598 memInfoBuilder.append(" Used RAM: ");
16599 memInfoBuilder.append(stringifyKBSize(
16600 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16601 memInfoBuilder.append("\n");
16602 memInfoBuilder.append(" Lost RAM: ");
16603 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16604 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16605 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16606 memInfoBuilder.append("\n");
16607 Slog.i(TAG, "Low on memory:");
16608 Slog.i(TAG, shortNativeBuilder.toString());
16609 Slog.i(TAG, fullJavaBuilder.toString());
16610 Slog.i(TAG, memInfoBuilder.toString());
16612 StringBuilder dropBuilder = new StringBuilder(1024);
16614 StringWriter oomSw = new StringWriter();
16615 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16616 StringWriter catSw = new StringWriter();
16617 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16618 String[] emptyArgs = new String[] { };
16619 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16621 String oomString = oomSw.toString();
16623 dropBuilder.append("Low on memory:");
16624 dropBuilder.append(stack);
16625 dropBuilder.append('\n');
16626 dropBuilder.append(fullNativeBuilder);
16627 dropBuilder.append(fullJavaBuilder);
16628 dropBuilder.append('\n');
16629 dropBuilder.append(memInfoBuilder);
16630 dropBuilder.append('\n');
16632 dropBuilder.append(oomString);
16633 dropBuilder.append('\n');
16635 StringWriter catSw = new StringWriter();
16636 synchronized (ActivityManagerService.this) {
16637 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16638 String[] emptyArgs = new String[] { };
16640 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16642 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16643 false, null).dumpLocked();
16645 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16648 dropBuilder.append(catSw.toString());
16649 addErrorToDropBox("lowmem", null, "system_server", null,
16650 null, tag.toString(), dropBuilder.toString(), null, null);
16651 //Slog.i(TAG, "Sent to dropbox:");
16652 //Slog.i(TAG, dropBuilder.toString());
16653 synchronized (ActivityManagerService.this) {
16654 long now = SystemClock.uptimeMillis();
16655 if (mLastMemUsageReportTime < now) {
16656 mLastMemUsageReportTime = now;
16662 * Searches array of arguments for the specified string
16663 * @param args array of argument strings
16664 * @param value value to search for
16665 * @return true if the value is contained in the array
16667 private static boolean scanArgs(String[] args, String value) {
16668 if (args != null) {
16669 for (String arg : args) {
16670 if (value.equals(arg)) {
16678 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16679 ContentProviderRecord cpr, boolean always) {
16680 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16682 if (!inLaunching || always) {
16683 synchronized (cpr) {
16684 cpr.launchingApp = null;
16687 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16688 String names[] = cpr.info.authority.split(";");
16689 for (int j = 0; j < names.length; j++) {
16690 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16694 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16695 ContentProviderConnection conn = cpr.connections.get(i);
16696 if (conn.waiting) {
16697 // If this connection is waiting for the provider, then we don't
16698 // need to mess with its process unless we are always removing
16699 // or for some reason the provider is not currently launching.
16700 if (inLaunching && !always) {
16704 ProcessRecord capp = conn.client;
16706 if (conn.stableCount > 0) {
16707 if (!capp.persistent && capp.thread != null
16709 && capp.pid != MY_PID) {
16710 capp.kill("depends on provider "
16711 + cpr.name.flattenToShortString()
16712 + " in dying proc " + (proc != null ? proc.processName : "??")
16713 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16715 } else if (capp.thread != null && conn.provider.provider != null) {
16717 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16718 } catch (RemoteException e) {
16720 // In the protocol here, we don't expect the client to correctly
16721 // clean up this connection, we'll just remove it.
16722 cpr.connections.remove(i);
16723 if (conn.client.conProviders.remove(conn)) {
16724 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16729 if (inLaunching && always) {
16730 mLaunchingProviders.remove(cpr);
16732 return inLaunching;
16736 * Main code for cleaning up a process when it has gone away. This is
16737 * called both as a result of the process dying, or directly when stopping
16738 * a process when running in single process mode.
16740 * @return Returns true if the given process has been restarted, so the
16741 * app that was passed in must remain on the process lists.
16743 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16744 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16745 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16747 removeLruProcessLocked(app);
16748 ProcessList.remove(app.pid);
16751 mProcessesToGc.remove(app);
16752 mPendingPssProcesses.remove(app);
16754 // Dismiss any open dialogs.
16755 if (app.crashDialog != null && !app.forceCrashReport) {
16756 app.crashDialog.dismiss();
16757 app.crashDialog = null;
16759 if (app.anrDialog != null) {
16760 app.anrDialog.dismiss();
16761 app.anrDialog = null;
16763 if (app.waitDialog != null) {
16764 app.waitDialog.dismiss();
16765 app.waitDialog = null;
16768 app.crashing = false;
16769 app.notResponding = false;
16771 app.resetPackageList(mProcessStats);
16772 app.unlinkDeathRecipient();
16773 app.makeInactive(mProcessStats);
16774 app.waitingToKill = null;
16775 app.forcingToForeground = null;
16776 updateProcessForegroundLocked(app, false, false);
16777 app.foregroundActivities = false;
16778 app.hasShownUi = false;
16779 app.treatLikeActivity = false;
16780 app.hasAboveClient = false;
16781 app.hasClientActivities = false;
16783 mServices.killServicesLocked(app, allowRestart);
16785 boolean restart = false;
16787 // Remove published content providers.
16788 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16789 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16790 final boolean always = app.bad || !allowRestart;
16791 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16792 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16793 // We left the provider in the launching list, need to
16798 cpr.provider = null;
16801 app.pubProviders.clear();
16803 // Take care of any launching providers waiting for this process.
16804 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16808 // Unregister from connected content providers.
16809 if (!app.conProviders.isEmpty()) {
16810 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16811 ContentProviderConnection conn = app.conProviders.get(i);
16812 conn.provider.connections.remove(conn);
16813 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16814 conn.provider.name);
16816 app.conProviders.clear();
16819 // At this point there may be remaining entries in mLaunchingProviders
16820 // where we were the only one waiting, so they are no longer of use.
16821 // Look for these and clean up if found.
16822 // XXX Commented out for now. Trying to figure out a way to reproduce
16823 // the actual situation to identify what is actually going on.
16825 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16826 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16827 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16828 synchronized (cpr) {
16829 cpr.launchingApp = null;
16836 skipCurrentReceiverLocked(app);
16838 // Unregister any receivers.
16839 for (int i = app.receivers.size() - 1; i >= 0; i--) {
16840 removeReceiverLocked(app.receivers.valueAt(i));
16842 app.receivers.clear();
16844 // If the app is undergoing backup, tell the backup manager about it
16845 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16846 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16847 + mBackupTarget.appInfo + " died during backup");
16849 IBackupManager bm = IBackupManager.Stub.asInterface(
16850 ServiceManager.getService(Context.BACKUP_SERVICE));
16851 bm.agentDisconnected(app.info.packageName);
16852 } catch (RemoteException e) {
16853 // can't happen; backup manager is local
16857 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16858 ProcessChangeItem item = mPendingProcessChanges.get(i);
16859 if (item.pid == app.pid) {
16860 mPendingProcessChanges.remove(i);
16861 mAvailProcessChanges.add(item);
16864 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16865 null).sendToTarget();
16867 // If the caller is restarting this app, then leave it in its
16868 // current lists and let the caller take care of it.
16873 if (!app.persistent || app.isolated) {
16874 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16875 "Removing non-persistent process during cleanup: " + app);
16876 if (!replacingPid) {
16877 removeProcessNameLocked(app.processName, app.uid);
16879 if (mHeavyWeightProcess == app) {
16880 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16881 mHeavyWeightProcess.userId, 0));
16882 mHeavyWeightProcess = null;
16884 } else if (!app.removed) {
16885 // This app is persistent, so we need to keep its record around.
16886 // If it is not already on the pending app list, add it there
16887 // and start a new process for it.
16888 if (mPersistentStartingProcesses.indexOf(app) < 0) {
16889 mPersistentStartingProcesses.add(app);
16893 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16894 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16895 mProcessesOnHold.remove(app);
16897 if (app == mHomeProcess) {
16898 mHomeProcess = null;
16900 if (app == mPreviousProcess) {
16901 mPreviousProcess = null;
16904 if (restart && !app.isolated) {
16905 // We have components that still need to be running in the
16906 // process, so re-launch it.
16908 ProcessList.remove(app.pid);
16910 addProcessNameLocked(app);
16911 startProcessLocked(app, "restart", app.processName);
16913 } else if (app.pid > 0 && app.pid != MY_PID) {
16916 synchronized (mPidsSelfLocked) {
16917 mPidsSelfLocked.remove(app.pid);
16918 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16920 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16921 if (app.isolated) {
16922 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16929 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16930 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16931 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16932 if (cpr.launchingApp == app) {
16939 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16940 // Look through the content providers we are waiting to have launched,
16941 // and if any run in this process then either schedule a restart of
16942 // the process or kill the client waiting for it if this process has
16944 boolean restart = false;
16945 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16946 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16947 if (cpr.launchingApp == app) {
16948 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16951 removeDyingProviderLocked(app, cpr, true);
16958 // =========================================================
16960 // =========================================================
16963 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16965 enforceNotIsolatedCaller("getServices");
16966 synchronized (this) {
16967 return mServices.getRunningServiceInfoLocked(maxNum, flags);
16972 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16973 enforceNotIsolatedCaller("getRunningServiceControlPanel");
16974 synchronized (this) {
16975 return mServices.getRunningServiceControlPanelLocked(name);
16980 public ComponentName startService(IApplicationThread caller, Intent service,
16981 String resolvedType, String callingPackage, int userId)
16982 throws TransactionTooLargeException {
16983 enforceNotIsolatedCaller("startService");
16984 // Refuse possible leaked file descriptors
16985 if (service != null && service.hasFileDescriptors() == true) {
16986 throw new IllegalArgumentException("File descriptors passed in Intent");
16989 if (callingPackage == null) {
16990 throw new IllegalArgumentException("callingPackage cannot be null");
16993 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16994 "startService: " + service + " type=" + resolvedType);
16995 synchronized(this) {
16996 final int callingPid = Binder.getCallingPid();
16997 final int callingUid = Binder.getCallingUid();
16998 final long origId = Binder.clearCallingIdentity();
16999 ComponentName res = mServices.startServiceLocked(caller, service,
17000 resolvedType, callingPid, callingUid, callingPackage, userId);
17001 Binder.restoreCallingIdentity(origId);
17006 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17007 String callingPackage, int userId)
17008 throws TransactionTooLargeException {
17009 synchronized(this) {
17010 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17011 "startServiceInPackage: " + service + " type=" + resolvedType);
17012 final long origId = Binder.clearCallingIdentity();
17013 ComponentName res = mServices.startServiceLocked(null, service,
17014 resolvedType, -1, uid, callingPackage, userId);
17015 Binder.restoreCallingIdentity(origId);
17021 public int stopService(IApplicationThread caller, Intent service,
17022 String resolvedType, int userId) {
17023 enforceNotIsolatedCaller("stopService");
17024 // Refuse possible leaked file descriptors
17025 if (service != null && service.hasFileDescriptors() == true) {
17026 throw new IllegalArgumentException("File descriptors passed in Intent");
17029 synchronized(this) {
17030 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17035 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17036 enforceNotIsolatedCaller("peekService");
17037 // Refuse possible leaked file descriptors
17038 if (service != null && service.hasFileDescriptors() == true) {
17039 throw new IllegalArgumentException("File descriptors passed in Intent");
17042 if (callingPackage == null) {
17043 throw new IllegalArgumentException("callingPackage cannot be null");
17046 synchronized(this) {
17047 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17052 public boolean stopServiceToken(ComponentName className, IBinder token,
17054 synchronized(this) {
17055 return mServices.stopServiceTokenLocked(className, token, startId);
17060 public void setServiceForeground(ComponentName className, IBinder token,
17061 int id, Notification notification, int flags) {
17062 synchronized(this) {
17063 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17068 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17069 boolean requireFull, String name, String callerPackage) {
17070 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17071 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17074 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17075 String className, int flags) {
17076 boolean result = false;
17077 // For apps that don't have pre-defined UIDs, check for permission
17078 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17079 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17080 if (ActivityManager.checkUidPermission(
17081 INTERACT_ACROSS_USERS,
17082 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17083 ComponentName comp = new ComponentName(aInfo.packageName, className);
17084 String msg = "Permission Denial: Component " + comp.flattenToShortString()
17085 + " requests FLAG_SINGLE_USER, but app does not hold "
17086 + INTERACT_ACROSS_USERS;
17088 throw new SecurityException(msg);
17090 // Permission passed
17093 } else if ("system".equals(componentProcessName)) {
17095 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17096 // Phone app and persistent apps are allowed to export singleuser providers.
17097 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17098 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17100 if (DEBUG_MU) Slog.v(TAG_MU,
17101 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17102 + Integer.toHexString(flags) + ") = " + result);
17107 * Checks to see if the caller is in the same app as the singleton
17108 * component, or the component is in a special app. It allows special apps
17109 * to export singleton components but prevents exporting singleton
17110 * components for regular apps.
17112 boolean isValidSingletonCall(int callingUid, int componentUid) {
17113 int componentAppId = UserHandle.getAppId(componentUid);
17114 return UserHandle.isSameApp(callingUid, componentUid)
17115 || componentAppId == Process.SYSTEM_UID
17116 || componentAppId == Process.PHONE_UID
17117 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17118 == PackageManager.PERMISSION_GRANTED;
17121 public int bindService(IApplicationThread caller, IBinder token, Intent service,
17122 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17123 int userId) throws TransactionTooLargeException {
17124 enforceNotIsolatedCaller("bindService");
17126 // Refuse possible leaked file descriptors
17127 if (service != null && service.hasFileDescriptors() == true) {
17128 throw new IllegalArgumentException("File descriptors passed in Intent");
17131 if (callingPackage == null) {
17132 throw new IllegalArgumentException("callingPackage cannot be null");
17135 synchronized(this) {
17136 return mServices.bindServiceLocked(caller, token, service,
17137 resolvedType, connection, flags, callingPackage, userId);
17141 public boolean unbindService(IServiceConnection connection) {
17142 synchronized (this) {
17143 return mServices.unbindServiceLocked(connection);
17147 public void publishService(IBinder token, Intent intent, IBinder service) {
17148 // Refuse possible leaked file descriptors
17149 if (intent != null && intent.hasFileDescriptors() == true) {
17150 throw new IllegalArgumentException("File descriptors passed in Intent");
17153 synchronized(this) {
17154 if (!(token instanceof ServiceRecord)) {
17155 throw new IllegalArgumentException("Invalid service token");
17157 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17161 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17162 // Refuse possible leaked file descriptors
17163 if (intent != null && intent.hasFileDescriptors() == true) {
17164 throw new IllegalArgumentException("File descriptors passed in Intent");
17167 synchronized(this) {
17168 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17172 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17173 synchronized(this) {
17174 if (!(token instanceof ServiceRecord)) {
17175 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17176 throw new IllegalArgumentException("Invalid service token");
17178 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17182 // =========================================================
17183 // BACKUP AND RESTORE
17184 // =========================================================
17186 // Cause the target app to be launched if necessary and its backup agent
17187 // instantiated. The backup agent will invoke backupAgentCreated() on the
17188 // activity manager to announce its creation.
17189 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17190 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17191 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17193 IPackageManager pm = AppGlobals.getPackageManager();
17194 ApplicationInfo app = null;
17196 app = pm.getApplicationInfo(packageName, 0, userId);
17197 } catch (RemoteException e) {
17198 // can't happen; package manager is process-local
17201 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17205 synchronized(this) {
17206 // !!! TODO: currently no check here that we're already bound
17207 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17208 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17209 synchronized (stats) {
17210 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17213 // Backup agent is now in use, its package can't be stopped.
17215 AppGlobals.getPackageManager().setPackageStoppedState(
17216 app.packageName, false, UserHandle.getUserId(app.uid));
17217 } catch (RemoteException e) {
17218 } catch (IllegalArgumentException e) {
17219 Slog.w(TAG, "Failed trying to unstop package "
17220 + app.packageName + ": " + e);
17223 BackupRecord r = new BackupRecord(ss, app, backupMode);
17224 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17225 ? new ComponentName(app.packageName, app.backupAgentName)
17226 : new ComponentName("android", "FullBackupAgent");
17227 // startProcessLocked() returns existing proc's record if it's already running
17228 ProcessRecord proc = startProcessLocked(app.processName, app,
17229 false, 0, "backup", hostingName, false, false, false);
17230 if (proc == null) {
17231 Slog.e(TAG, "Unable to start backup agent process " + r);
17235 // If the app is a regular app (uid >= 10000) and not the system server or phone
17236 // process, etc, then mark it as being in full backup so that certain calls to the
17237 // process can be blocked. This is not reset to false anywhere because we kill the
17238 // process after the full backup is done and the ProcessRecord will vaporize anyway.
17239 if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17240 proc.inFullBackup = true;
17244 mBackupAppName = app.packageName;
17246 // Try not to kill the process during backup
17247 updateOomAdjLocked(proc);
17249 // If the process is already attached, schedule the creation of the backup agent now.
17250 // If it is not yet live, this will be done when it attaches to the framework.
17251 if (proc.thread != null) {
17252 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17254 proc.thread.scheduleCreateBackupAgent(app,
17255 compatibilityInfoForPackageLocked(app), backupMode);
17256 } catch (RemoteException e) {
17257 // Will time out on the backup manager side
17260 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17262 // Invariants: at this point, the target app process exists and the application
17263 // is either already running or in the process of coming up. mBackupTarget and
17264 // mBackupAppName describe the app, so that when it binds back to the AM we
17265 // know that it's scheduled for a backup-agent operation.
17272 public void clearPendingBackup() {
17273 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17274 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17276 synchronized (this) {
17277 mBackupTarget = null;
17278 mBackupAppName = null;
17282 // A backup agent has just come up
17283 public void backupAgentCreated(String agentPackageName, IBinder agent) {
17284 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17287 synchronized(this) {
17288 if (!agentPackageName.equals(mBackupAppName)) {
17289 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17294 long oldIdent = Binder.clearCallingIdentity();
17296 IBackupManager bm = IBackupManager.Stub.asInterface(
17297 ServiceManager.getService(Context.BACKUP_SERVICE));
17298 bm.agentConnected(agentPackageName, agent);
17299 } catch (RemoteException e) {
17300 // can't happen; the backup manager service is local
17301 } catch (Exception e) {
17302 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17303 e.printStackTrace();
17305 Binder.restoreCallingIdentity(oldIdent);
17309 // done with this agent
17310 public void unbindBackupAgent(ApplicationInfo appInfo) {
17311 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17312 if (appInfo == null) {
17313 Slog.w(TAG, "unbind backup agent for null app");
17317 synchronized(this) {
17319 if (mBackupAppName == null) {
17320 Slog.w(TAG, "Unbinding backup agent with no active backup");
17324 if (!mBackupAppName.equals(appInfo.packageName)) {
17325 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17329 // Not backing this app up any more; reset its OOM adjustment
17330 final ProcessRecord proc = mBackupTarget.app;
17331 updateOomAdjLocked(proc);
17333 // If the app crashed during backup, 'thread' will be null here
17334 if (proc.thread != null) {
17336 proc.thread.scheduleDestroyBackupAgent(appInfo,
17337 compatibilityInfoForPackageLocked(appInfo));
17338 } catch (Exception e) {
17339 Slog.e(TAG, "Exception when unbinding backup agent:");
17340 e.printStackTrace();
17344 mBackupTarget = null;
17345 mBackupAppName = null;
17349 // =========================================================
17351 // =========================================================
17353 boolean isPendingBroadcastProcessLocked(int pid) {
17354 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17355 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17358 void skipPendingBroadcastLocked(int pid) {
17359 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17360 for (BroadcastQueue queue : mBroadcastQueues) {
17361 queue.skipPendingBroadcastLocked(pid);
17365 // The app just attached; send any pending broadcasts that it should receive
17366 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17367 boolean didSomething = false;
17368 for (BroadcastQueue queue : mBroadcastQueues) {
17369 didSomething |= queue.sendPendingBroadcastsLocked(app);
17371 return didSomething;
17374 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17375 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17376 enforceNotIsolatedCaller("registerReceiver");
17377 ArrayList<Intent> stickyIntents = null;
17378 ProcessRecord callerApp = null;
17381 synchronized(this) {
17382 if (caller != null) {
17383 callerApp = getRecordForAppLocked(caller);
17384 if (callerApp == null) {
17385 throw new SecurityException(
17386 "Unable to find app for caller " + caller
17387 + " (pid=" + Binder.getCallingPid()
17388 + ") when registering receiver " + receiver);
17390 if (callerApp.info.uid != Process.SYSTEM_UID &&
17391 !callerApp.pkgList.containsKey(callerPackage) &&
17392 !"android".equals(callerPackage)) {
17393 throw new SecurityException("Given caller package " + callerPackage
17394 + " is not running in process " + callerApp);
17396 callingUid = callerApp.info.uid;
17397 callingPid = callerApp.pid;
17399 callerPackage = null;
17400 callingUid = Binder.getCallingUid();
17401 callingPid = Binder.getCallingPid();
17404 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17405 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17407 Iterator<String> actions = filter.actionsIterator();
17408 if (actions == null) {
17409 ArrayList<String> noAction = new ArrayList<String>(1);
17410 noAction.add(null);
17411 actions = noAction.iterator();
17414 // Collect stickies of users
17415 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17416 while (actions.hasNext()) {
17417 String action = actions.next();
17418 for (int id : userIds) {
17419 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17420 if (stickies != null) {
17421 ArrayList<Intent> intents = stickies.get(action);
17422 if (intents != null) {
17423 if (stickyIntents == null) {
17424 stickyIntents = new ArrayList<Intent>();
17426 stickyIntents.addAll(intents);
17433 ArrayList<Intent> allSticky = null;
17434 if (stickyIntents != null) {
17435 final ContentResolver resolver = mContext.getContentResolver();
17436 // Look for any matching sticky broadcasts...
17437 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17438 Intent intent = stickyIntents.get(i);
17439 // If intent has scheme "content", it will need to acccess
17440 // provider that needs to lock mProviderMap in ActivityThread
17441 // and also it may need to wait application response, so we
17442 // cannot lock ActivityManagerService here.
17443 if (filter.match(resolver, intent, true, TAG) >= 0) {
17444 if (allSticky == null) {
17445 allSticky = new ArrayList<Intent>();
17447 allSticky.add(intent);
17452 // The first sticky in the list is returned directly back to the client.
17453 Intent sticky = allSticky != null ? allSticky.get(0) : null;
17454 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17455 if (receiver == null) {
17459 synchronized (this) {
17460 if (callerApp != null && (callerApp.thread == null
17461 || callerApp.thread.asBinder() != caller.asBinder())) {
17462 // Original caller already died
17465 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17467 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17469 if (rl.app != null) {
17470 rl.app.receivers.add(rl);
17473 receiver.asBinder().linkToDeath(rl, 0);
17474 } catch (RemoteException e) {
17477 rl.linkedToDeath = true;
17479 mRegisteredReceivers.put(receiver.asBinder(), rl);
17480 } else if (rl.uid != callingUid) {
17481 throw new IllegalArgumentException(
17482 "Receiver requested to register for uid " + callingUid
17483 + " was previously registered for uid " + rl.uid);
17484 } else if (rl.pid != callingPid) {
17485 throw new IllegalArgumentException(
17486 "Receiver requested to register for pid " + callingPid
17487 + " was previously registered for pid " + rl.pid);
17488 } else if (rl.userId != userId) {
17489 throw new IllegalArgumentException(
17490 "Receiver requested to register for user " + userId
17491 + " was previously registered for user " + rl.userId);
17493 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17494 permission, callingUid, userId);
17496 if (!bf.debugCheck()) {
17497 Slog.w(TAG, "==> For Dynamic broadcast");
17499 mReceiverResolver.addFilter(bf);
17501 // Enqueue broadcasts for all existing stickies that match
17503 if (allSticky != null) {
17504 ArrayList receivers = new ArrayList();
17507 final int stickyCount = allSticky.size();
17508 for (int i = 0; i < stickyCount; i++) {
17509 Intent intent = allSticky.get(i);
17510 BroadcastQueue queue = broadcastQueueForIntent(intent);
17511 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17512 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17513 null, 0, null, null, false, true, true, -1);
17514 queue.enqueueParallelBroadcastLocked(r);
17515 queue.scheduleBroadcastsLocked();
17523 public void unregisterReceiver(IIntentReceiver receiver) {
17524 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17526 final long origId = Binder.clearCallingIdentity();
17528 boolean doTrim = false;
17530 synchronized(this) {
17531 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17533 final BroadcastRecord r = rl.curBroadcast;
17534 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17535 final boolean doNext = r.queue.finishReceiverLocked(
17536 r, r.resultCode, r.resultData, r.resultExtras,
17537 r.resultAbort, false);
17540 r.queue.processNextBroadcast(false);
17544 if (rl.app != null) {
17545 rl.app.receivers.remove(rl);
17547 removeReceiverLocked(rl);
17548 if (rl.linkedToDeath) {
17549 rl.linkedToDeath = false;
17550 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17555 // If we actually concluded any broadcasts, we might now be able
17556 // to trim the recipients' apps from our working set
17558 trimApplications();
17563 Binder.restoreCallingIdentity(origId);
17567 void removeReceiverLocked(ReceiverList rl) {
17568 mRegisteredReceivers.remove(rl.receiver.asBinder());
17569 for (int i = rl.size() - 1; i >= 0; i--) {
17570 mReceiverResolver.removeFilter(rl.get(i));
17574 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17575 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17576 ProcessRecord r = mLruProcesses.get(i);
17577 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17579 r.thread.dispatchPackageBroadcast(cmd, packages);
17580 } catch (RemoteException ex) {
17586 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17587 int callingUid, int[] users) {
17588 // TODO: come back and remove this assumption to triage all broadcasts
17589 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17591 List<ResolveInfo> receivers = null;
17593 HashSet<ComponentName> singleUserReceivers = null;
17594 boolean scannedFirstReceivers = false;
17595 for (int user : users) {
17596 // Skip users that have Shell restrictions, with exception of always permitted
17597 // Shell broadcasts
17598 if (callingUid == Process.SHELL_UID
17599 && mUserController.hasUserRestriction(
17600 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17601 && !isPermittedShellBroadcast(intent)) {
17604 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17605 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17606 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17607 // If this is not the system user, we need to check for
17608 // any receivers that should be filtered out.
17609 for (int i=0; i<newReceivers.size(); i++) {
17610 ResolveInfo ri = newReceivers.get(i);
17611 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17612 newReceivers.remove(i);
17617 if (newReceivers != null && newReceivers.size() == 0) {
17618 newReceivers = null;
17620 if (receivers == null) {
17621 receivers = newReceivers;
17622 } else if (newReceivers != null) {
17623 // We need to concatenate the additional receivers
17624 // found with what we have do far. This would be easy,
17625 // but we also need to de-dup any receivers that are
17627 if (!scannedFirstReceivers) {
17628 // Collect any single user receivers we had already retrieved.
17629 scannedFirstReceivers = true;
17630 for (int i=0; i<receivers.size(); i++) {
17631 ResolveInfo ri = receivers.get(i);
17632 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17633 ComponentName cn = new ComponentName(
17634 ri.activityInfo.packageName, ri.activityInfo.name);
17635 if (singleUserReceivers == null) {
17636 singleUserReceivers = new HashSet<ComponentName>();
17638 singleUserReceivers.add(cn);
17642 // Add the new results to the existing results, tracking
17643 // and de-dupping single user receivers.
17644 for (int i=0; i<newReceivers.size(); i++) {
17645 ResolveInfo ri = newReceivers.get(i);
17646 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17647 ComponentName cn = new ComponentName(
17648 ri.activityInfo.packageName, ri.activityInfo.name);
17649 if (singleUserReceivers == null) {
17650 singleUserReceivers = new HashSet<ComponentName>();
17652 if (!singleUserReceivers.contains(cn)) {
17653 singleUserReceivers.add(cn);
17662 } catch (RemoteException ex) {
17663 // pm is in same process, this will never happen.
17668 private boolean isPermittedShellBroadcast(Intent intent) {
17669 // remote bugreport should always be allowed to be taken
17670 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17673 final int broadcastIntentLocked(ProcessRecord callerApp,
17674 String callerPackage, Intent intent, String resolvedType,
17675 IIntentReceiver resultTo, int resultCode, String resultData,
17676 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17677 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17678 intent = new Intent(intent);
17680 // By default broadcasts do not go to stopped apps.
17681 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17683 // If we have not finished booting, don't allow this to launch new processes.
17684 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17685 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17688 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17689 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17690 + " ordered=" + ordered + " userid=" + userId);
17691 if ((resultTo != null) && !ordered) {
17692 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17695 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17696 ALLOW_NON_FULL, "broadcast", callerPackage);
17698 // Make sure that the user who is receiving this broadcast is running.
17699 // If not, we will just skip it. Make an exception for shutdown broadcasts
17700 // and upgrade steps.
17702 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17703 if ((callingUid != Process.SYSTEM_UID
17704 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17705 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17706 Slog.w(TAG, "Skipping broadcast of " + intent
17707 + ": user " + userId + " is stopped");
17708 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17712 BroadcastOptions brOptions = null;
17713 if (bOptions != null) {
17714 brOptions = new BroadcastOptions(bOptions);
17715 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17716 // See if the caller is allowed to do this. Note we are checking against
17717 // the actual real caller (not whoever provided the operation as say a
17718 // PendingIntent), because that who is actually supplied the arguments.
17719 if (checkComponentPermission(
17720 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17721 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17722 != PackageManager.PERMISSION_GRANTED) {
17723 String msg = "Permission Denial: " + intent.getAction()
17724 + " broadcast from " + callerPackage + " (pid=" + callingPid
17725 + ", uid=" + callingUid + ")"
17727 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17729 throw new SecurityException(msg);
17734 // Verify that protected broadcasts are only being sent by system code,
17735 // and that system code is only sending protected broadcasts.
17736 final String action = intent.getAction();
17737 final boolean isProtectedBroadcast;
17739 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17740 } catch (RemoteException e) {
17741 Slog.w(TAG, "Remote exception", e);
17742 return ActivityManager.BROADCAST_SUCCESS;
17745 final boolean isCallerSystem;
17746 switch (UserHandle.getAppId(callingUid)) {
17747 case Process.ROOT_UID:
17748 case Process.SYSTEM_UID:
17749 case Process.PHONE_UID:
17750 case Process.BLUETOOTH_UID:
17751 case Process.NFC_UID:
17752 isCallerSystem = true;
17755 isCallerSystem = (callerApp != null) && callerApp.persistent;
17759 if (isCallerSystem) {
17760 if (isProtectedBroadcast
17761 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17762 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17763 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17764 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17765 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17766 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17767 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17768 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17769 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17770 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17771 // Broadcast is either protected, or it's a public action that
17772 // we've relaxed, so it's fine for system internals to send.
17774 // The vast majority of broadcasts sent from system internals
17775 // should be protected to avoid security holes, so yell loudly
17776 // to ensure we examine these cases.
17777 if (callerApp != null) {
17778 Log.wtf(TAG, "Sending non-protected broadcast " + action
17779 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17782 Log.wtf(TAG, "Sending non-protected broadcast " + action
17783 + " from system uid " + UserHandle.formatUid(callingUid)
17784 + " pkg " + callerPackage,
17790 if (isProtectedBroadcast) {
17791 String msg = "Permission Denial: not allowed to send broadcast "
17792 + action + " from pid="
17793 + callingPid + ", uid=" + callingUid;
17795 throw new SecurityException(msg);
17797 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17798 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17799 // Special case for compatibility: we don't want apps to send this,
17800 // but historically it has not been protected and apps may be using it
17801 // to poke their own app widget. So, instead of making it protected,
17802 // just limit it to the caller.
17803 if (callerPackage == null) {
17804 String msg = "Permission Denial: not allowed to send broadcast "
17805 + action + " from unknown caller.";
17807 throw new SecurityException(msg);
17808 } else if (intent.getComponent() != null) {
17809 // They are good enough to send to an explicit component... verify
17810 // it is being sent to the calling app.
17811 if (!intent.getComponent().getPackageName().equals(
17813 String msg = "Permission Denial: not allowed to send broadcast "
17815 + intent.getComponent().getPackageName() + " from "
17818 throw new SecurityException(msg);
17821 // Limit broadcast to their own package.
17822 intent.setPackage(callerPackage);
17827 if (action != null) {
17829 case Intent.ACTION_UID_REMOVED:
17830 case Intent.ACTION_PACKAGE_REMOVED:
17831 case Intent.ACTION_PACKAGE_CHANGED:
17832 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17833 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17834 case Intent.ACTION_PACKAGES_SUSPENDED:
17835 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17836 // Handle special intents: if this broadcast is from the package
17837 // manager about a package being removed, we need to remove all of
17838 // its activities from the history stack.
17839 if (checkComponentPermission(
17840 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17841 callingPid, callingUid, -1, true)
17842 != PackageManager.PERMISSION_GRANTED) {
17843 String msg = "Permission Denial: " + intent.getAction()
17844 + " broadcast from " + callerPackage + " (pid=" + callingPid
17845 + ", uid=" + callingUid + ")"
17847 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17849 throw new SecurityException(msg);
17852 case Intent.ACTION_UID_REMOVED:
17853 final Bundle intentExtras = intent.getExtras();
17854 final int uid = intentExtras != null
17855 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17857 mBatteryStatsService.removeUid(uid);
17858 mAppOpsService.uidRemoved(uid);
17861 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17862 // If resources are unavailable just force stop all those packages
17863 // and flush the attribute cache as well.
17865 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17866 if (list != null && list.length > 0) {
17867 for (int i = 0; i < list.length; i++) {
17868 forceStopPackageLocked(list[i], -1, false, true, true,
17869 false, false, userId, "storage unmount");
17871 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17872 sendPackageBroadcastLocked(
17873 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17877 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17878 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17880 case Intent.ACTION_PACKAGE_REMOVED:
17881 case Intent.ACTION_PACKAGE_CHANGED:
17882 Uri data = intent.getData();
17884 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17885 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17886 final boolean replacing =
17887 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17888 final boolean killProcess =
17889 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17890 final boolean fullUninstall = removed && !replacing;
17893 forceStopPackageLocked(ssp, UserHandle.getAppId(
17894 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17895 false, true, true, false, fullUninstall, userId,
17896 removed ? "pkg removed" : "pkg changed");
17898 final int cmd = killProcess
17899 ? IApplicationThread.PACKAGE_REMOVED
17900 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17901 sendPackageBroadcastLocked(cmd,
17902 new String[] {ssp}, userId);
17903 if (fullUninstall) {
17904 mAppOpsService.packageRemoved(
17905 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17907 // Remove all permissions granted from/to this package
17908 removeUriPermissionsForPackageLocked(ssp, userId, true);
17910 removeTasksByPackageNameLocked(ssp, userId);
17912 // Hide the "unsupported display" dialog if necessary.
17913 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17914 mUnsupportedDisplaySizeDialog.getPackageName())) {
17915 mUnsupportedDisplaySizeDialog.dismiss();
17916 mUnsupportedDisplaySizeDialog = null;
17918 mCompatModePackages.handlePackageUninstalledLocked(ssp);
17919 mBatteryStatsService.notePackageUninstalled(ssp);
17923 killPackageProcessesLocked(ssp, UserHandle.getAppId(
17924 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17925 userId, ProcessList.INVALID_ADJ,
17926 false, true, true, false, "change " + ssp);
17928 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17929 intent.getStringArrayExtra(
17930 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17934 case Intent.ACTION_PACKAGES_SUSPENDED:
17935 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17936 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17937 intent.getAction());
17938 final String[] packageNames = intent.getStringArrayExtra(
17939 Intent.EXTRA_CHANGED_PACKAGE_LIST);
17940 final int userHandle = intent.getIntExtra(
17941 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17943 synchronized(ActivityManagerService.this) {
17944 mRecentTasks.onPackagesSuspendedChanged(
17945 packageNames, suspended, userHandle);
17950 case Intent.ACTION_PACKAGE_REPLACED:
17952 final Uri data = intent.getData();
17954 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17955 final ApplicationInfo aInfo =
17956 getPackageManagerInternalLocked().getApplicationInfo(
17959 if (aInfo == null) {
17960 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17961 + " ssp=" + ssp + " data=" + data);
17962 return ActivityManager.BROADCAST_SUCCESS;
17964 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17965 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17966 new String[] {ssp}, userId);
17970 case Intent.ACTION_PACKAGE_ADDED:
17972 // Special case for adding a package: by default turn on compatibility mode.
17973 Uri data = intent.getData();
17975 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17976 final boolean replacing =
17977 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17978 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17981 ApplicationInfo ai = AppGlobals.getPackageManager().
17982 getApplicationInfo(ssp, 0, 0);
17983 mBatteryStatsService.notePackageInstalled(ssp,
17984 ai != null ? ai.versionCode : 0);
17985 } catch (RemoteException e) {
17990 case Intent.ACTION_PACKAGE_DATA_CLEARED:
17992 Uri data = intent.getData();
17994 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17995 // Hide the "unsupported display" dialog if necessary.
17996 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17997 mUnsupportedDisplaySizeDialog.getPackageName())) {
17998 mUnsupportedDisplaySizeDialog.dismiss();
17999 mUnsupportedDisplaySizeDialog = null;
18001 mCompatModePackages.handlePackageDataClearedLocked(ssp);
18005 case Intent.ACTION_TIMEZONE_CHANGED:
18006 // If this is the time zone changed action, queue up a message that will reset
18007 // the timezone of all currently running processes. This message will get
18008 // queued up before the broadcast happens.
18009 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18011 case Intent.ACTION_TIME_CHANGED:
18012 // If the user set the time, let all running processes know.
18013 final int is24Hour =
18014 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18016 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18017 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18018 synchronized (stats) {
18019 stats.noteCurrentTimeChangedLocked();
18022 case Intent.ACTION_CLEAR_DNS_CACHE:
18023 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18025 case Proxy.PROXY_CHANGE_ACTION:
18026 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18027 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18029 case android.hardware.Camera.ACTION_NEW_PICTURE:
18030 case android.hardware.Camera.ACTION_NEW_VIDEO:
18031 // These broadcasts are no longer allowed by the system, since they can
18032 // cause significant thrashing at a crictical point (using the camera).
18033 // Apps should use JobScehduler to monitor for media provider changes.
18034 Slog.w(TAG, action + " no longer allowed; dropping from "
18035 + UserHandle.formatUid(callingUid));
18036 if (resultTo != null) {
18037 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18039 queue.performReceiveLocked(callerApp, resultTo, intent,
18040 Activity.RESULT_CANCELED, null, null,
18041 false, false, userId);
18042 } catch (RemoteException e) {
18043 Slog.w(TAG, "Failure ["
18044 + queue.mQueueName + "] sending broadcast result of "
18049 // Lie; we don't want to crash the app.
18050 return ActivityManager.BROADCAST_SUCCESS;
18054 // Add to the sticky list if requested.
18056 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18057 callingPid, callingUid)
18058 != PackageManager.PERMISSION_GRANTED) {
18059 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18060 + callingPid + ", uid=" + callingUid
18061 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18063 throw new SecurityException(msg);
18065 if (requiredPermissions != null && requiredPermissions.length > 0) {
18066 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18067 + " and enforce permissions " + Arrays.toString(requiredPermissions));
18068 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18070 if (intent.getComponent() != null) {
18071 throw new SecurityException(
18072 "Sticky broadcasts can't target a specific component");
18074 // We use userId directly here, since the "all" target is maintained
18075 // as a separate set of sticky broadcasts.
18076 if (userId != UserHandle.USER_ALL) {
18077 // But first, if this is not a broadcast to all users, then
18078 // make sure it doesn't conflict with an existing broadcast to
18080 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18081 UserHandle.USER_ALL);
18082 if (stickies != null) {
18083 ArrayList<Intent> list = stickies.get(intent.getAction());
18084 if (list != null) {
18085 int N = list.size();
18087 for (i=0; i<N; i++) {
18088 if (intent.filterEquals(list.get(i))) {
18089 throw new IllegalArgumentException(
18090 "Sticky broadcast " + intent + " for user "
18091 + userId + " conflicts with existing global broadcast");
18097 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18098 if (stickies == null) {
18099 stickies = new ArrayMap<>();
18100 mStickyBroadcasts.put(userId, stickies);
18102 ArrayList<Intent> list = stickies.get(intent.getAction());
18103 if (list == null) {
18104 list = new ArrayList<>();
18105 stickies.put(intent.getAction(), list);
18107 final int stickiesCount = list.size();
18109 for (i = 0; i < stickiesCount; i++) {
18110 if (intent.filterEquals(list.get(i))) {
18111 // This sticky already exists, replace it.
18112 list.set(i, new Intent(intent));
18116 if (i >= stickiesCount) {
18117 list.add(new Intent(intent));
18122 if (userId == UserHandle.USER_ALL) {
18123 // Caller wants broadcast to go to all started users.
18124 users = mUserController.getStartedUserArrayLocked();
18126 // Caller wants broadcast to go to one specific user.
18127 users = new int[] {userId};
18130 // Figure out who all will receive this broadcast.
18131 List receivers = null;
18132 List<BroadcastFilter> registeredReceivers = null;
18133 // Need to resolve the intent to interested receivers...
18134 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18136 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18138 if (intent.getComponent() == null) {
18139 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18140 // Query one target user at a time, excluding shell-restricted users
18141 for (int i = 0; i < users.length; i++) {
18142 if (mUserController.hasUserRestriction(
18143 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18146 List<BroadcastFilter> registeredReceiversForUser =
18147 mReceiverResolver.queryIntent(intent,
18148 resolvedType, false, users[i]);
18149 if (registeredReceivers == null) {
18150 registeredReceivers = registeredReceiversForUser;
18151 } else if (registeredReceiversForUser != null) {
18152 registeredReceivers.addAll(registeredReceiversForUser);
18156 registeredReceivers = mReceiverResolver.queryIntent(intent,
18157 resolvedType, false, userId);
18161 final boolean replacePending =
18162 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18164 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18165 + " replacePending=" + replacePending);
18167 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18168 if (!ordered && NR > 0) {
18169 // If we are not serializing this broadcast, then send the
18170 // registered receivers separately so they don't wait for the
18171 // components to be launched.
18172 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18173 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18174 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18175 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18176 resultExtras, ordered, sticky, false, userId);
18177 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18178 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18180 queue.enqueueParallelBroadcastLocked(r);
18181 queue.scheduleBroadcastsLocked();
18183 registeredReceivers = null;
18187 // Merge into one list.
18189 if (receivers != null) {
18190 // A special case for PACKAGE_ADDED: do not allow the package
18191 // being added to see this broadcast. This prevents them from
18192 // using this as a back door to get run as soon as they are
18193 // installed. Maybe in the future we want to have a special install
18194 // broadcast or such for apps, but we'd like to deliberately make
18196 String skipPackages[] = null;
18197 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18198 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18199 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18200 Uri data = intent.getData();
18201 if (data != null) {
18202 String pkgName = data.getSchemeSpecificPart();
18203 if (pkgName != null) {
18204 skipPackages = new String[] { pkgName };
18207 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18208 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18210 if (skipPackages != null && (skipPackages.length > 0)) {
18211 for (String skipPackage : skipPackages) {
18212 if (skipPackage != null) {
18213 int NT = receivers.size();
18214 for (int it=0; it<NT; it++) {
18215 ResolveInfo curt = (ResolveInfo)receivers.get(it);
18216 if (curt.activityInfo.packageName.equals(skipPackage)) {
18217 receivers.remove(it);
18226 int NT = receivers != null ? receivers.size() : 0;
18228 ResolveInfo curt = null;
18229 BroadcastFilter curr = null;
18230 while (it < NT && ir < NR) {
18231 if (curt == null) {
18232 curt = (ResolveInfo)receivers.get(it);
18234 if (curr == null) {
18235 curr = registeredReceivers.get(ir);
18237 if (curr.getPriority() >= curt.priority) {
18238 // Insert this broadcast record into the final list.
18239 receivers.add(it, curr);
18245 // Skip to the next ResolveInfo in the final list.
18252 if (receivers == null) {
18253 receivers = new ArrayList();
18255 receivers.add(registeredReceivers.get(ir));
18259 if ((receivers != null && receivers.size() > 0)
18260 || resultTo != null) {
18261 BroadcastQueue queue = broadcastQueueForIntent(intent);
18262 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18263 callerPackage, callingPid, callingUid, resolvedType,
18264 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18265 resultData, resultExtras, ordered, sticky, false, userId);
18267 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18268 + ": prev had " + queue.mOrderedBroadcasts.size());
18269 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18270 "Enqueueing broadcast " + r.intent.getAction());
18272 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18274 queue.enqueueOrderedBroadcastLocked(r);
18275 queue.scheduleBroadcastsLocked();
18278 // There was nobody interested in the broadcast, but we still want to record
18279 // that it happened.
18280 if (intent.getComponent() == null && intent.getPackage() == null
18281 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18282 // This was an implicit broadcast... let's record it for posterity.
18283 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18287 return ActivityManager.BROADCAST_SUCCESS;
18290 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18291 int skipCount, long dispatchTime) {
18292 final long now = SystemClock.elapsedRealtime();
18293 if (mCurBroadcastStats == null ||
18294 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18295 mLastBroadcastStats = mCurBroadcastStats;
18296 if (mLastBroadcastStats != null) {
18297 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18298 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18300 mCurBroadcastStats = new BroadcastStats();
18302 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18305 final Intent verifyBroadcastLocked(Intent intent) {
18306 // Refuse possible leaked file descriptors
18307 if (intent != null && intent.hasFileDescriptors() == true) {
18308 throw new IllegalArgumentException("File descriptors passed in Intent");
18311 int flags = intent.getFlags();
18313 if (!mProcessesReady) {
18314 // if the caller really truly claims to know what they're doing, go
18315 // ahead and allow the broadcast without launching any receivers
18316 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18317 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18318 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18319 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18320 + " before boot completion");
18321 throw new IllegalStateException("Cannot broadcast before boot completed");
18325 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18326 throw new IllegalArgumentException(
18327 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18333 public final int broadcastIntent(IApplicationThread caller,
18334 Intent intent, String resolvedType, IIntentReceiver resultTo,
18335 int resultCode, String resultData, Bundle resultExtras,
18336 String[] requiredPermissions, int appOp, Bundle bOptions,
18337 boolean serialized, boolean sticky, int userId) {
18338 enforceNotIsolatedCaller("broadcastIntent");
18339 synchronized(this) {
18340 intent = verifyBroadcastLocked(intent);
18342 final ProcessRecord callerApp = getRecordForAppLocked(caller);
18343 final int callingPid = Binder.getCallingPid();
18344 final int callingUid = Binder.getCallingUid();
18345 final long origId = Binder.clearCallingIdentity();
18346 int res = broadcastIntentLocked(callerApp,
18347 callerApp != null ? callerApp.info.packageName : null,
18348 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18349 requiredPermissions, appOp, bOptions, serialized, sticky,
18350 callingPid, callingUid, userId);
18351 Binder.restoreCallingIdentity(origId);
18357 int broadcastIntentInPackage(String packageName, int uid,
18358 Intent intent, String resolvedType, IIntentReceiver resultTo,
18359 int resultCode, String resultData, Bundle resultExtras,
18360 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18362 synchronized(this) {
18363 intent = verifyBroadcastLocked(intent);
18365 final long origId = Binder.clearCallingIdentity();
18366 String[] requiredPermissions = requiredPermission == null ? null
18367 : new String[] {requiredPermission};
18368 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18369 resultTo, resultCode, resultData, resultExtras,
18370 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18371 sticky, -1, uid, userId);
18372 Binder.restoreCallingIdentity(origId);
18377 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18378 // Refuse possible leaked file descriptors
18379 if (intent != null && intent.hasFileDescriptors() == true) {
18380 throw new IllegalArgumentException("File descriptors passed in Intent");
18383 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18384 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18386 synchronized(this) {
18387 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18388 != PackageManager.PERMISSION_GRANTED) {
18389 String msg = "Permission Denial: unbroadcastIntent() from pid="
18390 + Binder.getCallingPid()
18391 + ", uid=" + Binder.getCallingUid()
18392 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18394 throw new SecurityException(msg);
18396 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18397 if (stickies != null) {
18398 ArrayList<Intent> list = stickies.get(intent.getAction());
18399 if (list != null) {
18400 int N = list.size();
18402 for (i=0; i<N; i++) {
18403 if (intent.filterEquals(list.get(i))) {
18408 if (list.size() <= 0) {
18409 stickies.remove(intent.getAction());
18412 if (stickies.size() <= 0) {
18413 mStickyBroadcasts.remove(userId);
18419 void backgroundServicesFinishedLocked(int userId) {
18420 for (BroadcastQueue queue : mBroadcastQueues) {
18421 queue.backgroundServicesFinishedLocked(userId);
18425 public void finishReceiver(IBinder who, int resultCode, String resultData,
18426 Bundle resultExtras, boolean resultAbort, int flags) {
18427 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18429 // Refuse possible leaked file descriptors
18430 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18431 throw new IllegalArgumentException("File descriptors passed in Bundle");
18434 final long origId = Binder.clearCallingIdentity();
18436 boolean doNext = false;
18439 synchronized(this) {
18440 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18441 ? mFgBroadcastQueue : mBgBroadcastQueue;
18442 r = queue.getMatchingOrderedReceiver(who);
18444 doNext = r.queue.finishReceiverLocked(r, resultCode,
18445 resultData, resultExtras, resultAbort, true);
18450 r.queue.processNextBroadcast(false);
18452 trimApplications();
18454 Binder.restoreCallingIdentity(origId);
18458 // =========================================================
18460 // =========================================================
18462 public boolean startInstrumentation(ComponentName className,
18463 String profileFile, int flags, Bundle arguments,
18464 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18465 int userId, String abiOverride) {
18466 enforceNotIsolatedCaller("startInstrumentation");
18467 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18468 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18469 // Refuse possible leaked file descriptors
18470 if (arguments != null && arguments.hasFileDescriptors()) {
18471 throw new IllegalArgumentException("File descriptors passed in Bundle");
18474 synchronized(this) {
18475 InstrumentationInfo ii = null;
18476 ApplicationInfo ai = null;
18478 ii = mContext.getPackageManager().getInstrumentationInfo(
18479 className, STOCK_PM_FLAGS);
18480 ai = AppGlobals.getPackageManager().getApplicationInfo(
18481 ii.targetPackage, STOCK_PM_FLAGS, userId);
18482 } catch (PackageManager.NameNotFoundException e) {
18483 } catch (RemoteException e) {
18486 reportStartInstrumentationFailureLocked(watcher, className,
18487 "Unable to find instrumentation info for: " + className);
18491 reportStartInstrumentationFailureLocked(watcher, className,
18492 "Unable to find instrumentation target package: " + ii.targetPackage);
18495 if (!ai.hasCode()) {
18496 reportStartInstrumentationFailureLocked(watcher, className,
18497 "Instrumentation target has no code: " + ii.targetPackage);
18501 int match = mContext.getPackageManager().checkSignatures(
18502 ii.targetPackage, ii.packageName);
18503 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18504 String msg = "Permission Denial: starting instrumentation "
18505 + className + " from pid="
18506 + Binder.getCallingPid()
18507 + ", uid=" + Binder.getCallingPid()
18508 + " not allowed because package " + ii.packageName
18509 + " does not have a signature matching the target "
18510 + ii.targetPackage;
18511 reportStartInstrumentationFailureLocked(watcher, className, msg);
18512 throw new SecurityException(msg);
18515 final long origId = Binder.clearCallingIdentity();
18516 // Instrumentation can kill and relaunch even persistent processes
18517 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18519 ProcessRecord app = addAppLocked(ai, false, abiOverride);
18520 app.instrumentationClass = className;
18521 app.instrumentationInfo = ai;
18522 app.instrumentationProfileFile = profileFile;
18523 app.instrumentationArguments = arguments;
18524 app.instrumentationWatcher = watcher;
18525 app.instrumentationUiAutomationConnection = uiAutomationConnection;
18526 app.instrumentationResultClass = className;
18527 Binder.restoreCallingIdentity(origId);
18534 * Report errors that occur while attempting to start Instrumentation. Always writes the
18535 * error to the logs, but if somebody is watching, send the report there too. This enables
18536 * the "am" command to report errors with more information.
18538 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
18539 * @param cn The component name of the instrumentation.
18540 * @param report The error report.
18542 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18543 ComponentName cn, String report) {
18544 Slog.w(TAG, report);
18545 if (watcher != null) {
18546 Bundle results = new Bundle();
18547 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18548 results.putString("Error", report);
18549 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18553 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18554 if (app.instrumentationWatcher != null) {
18555 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18556 app.instrumentationClass, resultCode, results);
18559 // Can't call out of the system process with a lock held, so post a message.
18560 if (app.instrumentationUiAutomationConnection != null) {
18561 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18562 app.instrumentationUiAutomationConnection).sendToTarget();
18565 app.instrumentationWatcher = null;
18566 app.instrumentationUiAutomationConnection = null;
18567 app.instrumentationClass = null;
18568 app.instrumentationInfo = null;
18569 app.instrumentationProfileFile = null;
18570 app.instrumentationArguments = null;
18572 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18576 public void finishInstrumentation(IApplicationThread target,
18577 int resultCode, Bundle results) {
18578 int userId = UserHandle.getCallingUserId();
18579 // Refuse possible leaked file descriptors
18580 if (results != null && results.hasFileDescriptors()) {
18581 throw new IllegalArgumentException("File descriptors passed in Intent");
18584 synchronized(this) {
18585 ProcessRecord app = getRecordForAppLocked(target);
18587 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18590 final long origId = Binder.clearCallingIdentity();
18591 finishInstrumentationLocked(app, resultCode, results);
18592 Binder.restoreCallingIdentity(origId);
18596 // =========================================================
18598 // =========================================================
18600 public ConfigurationInfo getDeviceConfigurationInfo() {
18601 ConfigurationInfo config = new ConfigurationInfo();
18602 synchronized (this) {
18603 config.reqTouchScreen = mConfiguration.touchscreen;
18604 config.reqKeyboardType = mConfiguration.keyboard;
18605 config.reqNavigation = mConfiguration.navigation;
18606 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18607 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18608 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18610 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18611 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18612 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18614 config.reqGlEsVersion = GL_ES_VERSION;
18619 ActivityStack getFocusedStack() {
18620 return mStackSupervisor.getFocusedStack();
18624 public int getFocusedStackId() throws RemoteException {
18625 ActivityStack focusedStack = getFocusedStack();
18626 if (focusedStack != null) {
18627 return focusedStack.getStackId();
18632 public Configuration getConfiguration() {
18634 synchronized(this) {
18635 ci = new Configuration(mConfiguration);
18636 ci.userSetLocale = false;
18642 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18643 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18644 synchronized (this) {
18645 mSuppressResizeConfigChanges = suppress;
18650 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18651 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18652 if (fromStackId == HOME_STACK_ID) {
18653 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18655 synchronized (this) {
18656 final long origId = Binder.clearCallingIdentity();
18658 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18660 Binder.restoreCallingIdentity(origId);
18666 public void updatePersistentConfiguration(Configuration values) {
18667 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18668 "updateConfiguration()");
18669 enforceWriteSettingsPermission("updateConfiguration()");
18670 if (values == null) {
18671 throw new NullPointerException("Configuration must not be null");
18674 int userId = UserHandle.getCallingUserId();
18676 synchronized(this) {
18677 final long origId = Binder.clearCallingIdentity();
18678 updateConfigurationLocked(values, null, false, true, userId);
18679 Binder.restoreCallingIdentity(origId);
18683 private void updateFontScaleIfNeeded() {
18684 final int currentUserId;
18685 synchronized(this) {
18686 currentUserId = mUserController.getCurrentUserIdLocked();
18688 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18689 FONT_SCALE, 1.0f, currentUserId);
18690 if (mConfiguration.fontScale != scaleFactor) {
18691 final Configuration configuration = mWindowManager.computeNewConfiguration();
18692 configuration.fontScale = scaleFactor;
18693 updatePersistentConfiguration(configuration);
18697 private void enforceWriteSettingsPermission(String func) {
18698 int uid = Binder.getCallingUid();
18699 if (uid == Process.ROOT_UID) {
18703 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18704 Settings.getPackageNameForUid(mContext, uid), false)) {
18708 String msg = "Permission Denial: " + func + " from pid="
18709 + Binder.getCallingPid()
18711 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18713 throw new SecurityException(msg);
18716 public void updateConfiguration(Configuration values) {
18717 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18718 "updateConfiguration()");
18720 synchronized(this) {
18721 if (values == null && mWindowManager != null) {
18722 // sentinel: fetch the current configuration from the window manager
18723 values = mWindowManager.computeNewConfiguration();
18726 if (mWindowManager != null) {
18727 mProcessList.applyDisplaySize(mWindowManager);
18730 final long origId = Binder.clearCallingIdentity();
18731 if (values != null) {
18732 Settings.System.clearConfiguration(values);
18734 updateConfigurationLocked(values, null, false);
18735 Binder.restoreCallingIdentity(origId);
18739 void updateUserConfigurationLocked() {
18740 Configuration configuration = new Configuration(mConfiguration);
18741 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18742 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18743 updateConfigurationLocked(configuration, null, false);
18746 boolean updateConfigurationLocked(Configuration values,
18747 ActivityRecord starting, boolean initLocale) {
18748 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18749 return updateConfigurationLocked(values, starting, initLocale, false,
18750 UserHandle.USER_NULL);
18753 // To cache the list of supported system locales
18754 private String[] mSupportedSystemLocales = null;
18757 * Do either or both things: (1) change the current configuration, and (2)
18758 * make sure the given activity is running with the (now) current
18759 * configuration. Returns true if the activity has been left running, or
18760 * false if <var>starting</var> is being destroyed to match the new
18763 * @param userId is only used when persistent parameter is set to true to persist configuration
18764 * for that particular user
18766 private boolean updateConfigurationLocked(Configuration values,
18767 ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18770 if (mWindowManager != null) {
18771 mWindowManager.deferSurfaceLayout();
18773 if (values != null) {
18774 Configuration newConfig = new Configuration(mConfiguration);
18775 changes = newConfig.updateFrom(values);
18776 if (changes != 0) {
18777 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18778 "Updating configuration to: " + values);
18780 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18782 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18783 final LocaleList locales = values.getLocales();
18784 int bestLocaleIndex = 0;
18785 if (locales.size() > 1) {
18786 if (mSupportedSystemLocales == null) {
18787 mSupportedSystemLocales =
18788 Resources.getSystem().getAssets().getLocales();
18790 bestLocaleIndex = Math.max(0,
18791 locales.getFirstMatchIndex(mSupportedSystemLocales));
18793 SystemProperties.set("persist.sys.locale",
18794 locales.get(bestLocaleIndex).toLanguageTag());
18795 LocaleList.setDefault(locales, bestLocaleIndex);
18796 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18797 locales.get(bestLocaleIndex)));
18800 mConfigurationSeq++;
18801 if (mConfigurationSeq <= 0) {
18802 mConfigurationSeq = 1;
18804 newConfig.seq = mConfigurationSeq;
18805 mConfiguration = newConfig;
18806 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18807 mUsageStatsService.reportConfigurationChange(newConfig,
18808 mUserController.getCurrentUserIdLocked());
18809 //mUsageStatsService.noteStartConfig(newConfig);
18811 final Configuration configCopy = new Configuration(mConfiguration);
18813 // TODO: If our config changes, should we auto dismiss any currently
18814 // showing dialogs?
18815 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18817 AttributeCache ac = AttributeCache.instance();
18819 ac.updateConfiguration(configCopy);
18822 // Make sure all resources in our process are updated
18823 // right now, so that anyone who is going to retrieve
18824 // resource values after we return will be sure to get
18825 // the new ones. This is especially important during
18826 // boot, where the first config change needs to guarantee
18827 // all resources have that config before following boot
18828 // code is executed.
18829 mSystemThread.applyConfigurationToResources(configCopy);
18831 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18832 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18833 msg.obj = new Configuration(configCopy);
18835 mHandler.sendMessage(msg);
18838 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18839 if (isDensityChange) {
18840 // Reset the unsupported display size dialog.
18841 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18843 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18844 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18847 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18848 ProcessRecord app = mLruProcesses.get(i);
18850 if (app.thread != null) {
18851 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18852 + app.processName + " new config " + mConfiguration);
18853 app.thread.scheduleConfigurationChanged(configCopy);
18855 } catch (Exception e) {
18858 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18859 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18860 | Intent.FLAG_RECEIVER_REPLACE_PENDING
18861 | Intent.FLAG_RECEIVER_FOREGROUND);
18862 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18863 null, AppOpsManager.OP_NONE, null, false, false,
18864 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18865 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18866 // Tell the shortcut manager that the system locale changed. It needs to know
18867 // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18868 // we "push" from here, rather than having the service listen to the broadcast.
18869 final ShortcutServiceInternal shortcutService =
18870 LocalServices.getService(ShortcutServiceInternal.class);
18871 if (shortcutService != null) {
18872 shortcutService.onSystemLocaleChangedNoLock();
18875 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18876 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18877 if (!mProcessesReady) {
18878 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18880 broadcastIntentLocked(null, null, intent,
18881 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18882 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18885 // Update the configuration with WM first and check if any of the stacks need to be
18886 // resized due to the configuration change. If so, resize the stacks now and do any
18887 // relaunches if necessary. This way we don't need to relaunch again below in
18888 // ensureActivityConfigurationLocked().
18889 if (mWindowManager != null) {
18890 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18891 if (resizedStacks != null) {
18892 for (int stackId : resizedStacks) {
18893 final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18894 mStackSupervisor.resizeStackLocked(
18895 stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18901 boolean kept = true;
18902 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18903 // mainStack is null during startup.
18904 if (mainStack != null) {
18905 if (changes != 0 && starting == null) {
18906 // If the configuration changed, and the caller is not already
18907 // in the process of starting an activity, then find the top
18908 // activity to check if its configuration needs to change.
18909 starting = mainStack.topRunningActivityLocked();
18912 if (starting != null) {
18913 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18914 // And we need to make sure at this point that all other activities
18915 // are made visible with the correct configuration.
18916 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18917 !PRESERVE_WINDOWS);
18920 if (mWindowManager != null) {
18921 mWindowManager.continueSurfaceLayout();
18927 * Decide based on the configuration whether we should shouw the ANR,
18928 * crash, etc dialogs. The idea is that if there is no affordnace to
18929 * press the on-screen buttons, we shouldn't show the dialog.
18931 * A thought: SystemUI might also want to get told about this, the Power
18932 * dialog / global actions also might want different behaviors.
18934 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18935 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18936 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18937 && config.navigation == Configuration.NAVIGATION_NONAV);
18938 final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18939 == Configuration.UI_MODE_TYPE_CAR);
18940 return inputMethodExists && uiIsNotCarType && !inVrMode;
18944 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18945 synchronized (this) {
18946 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18947 if (srec != null) {
18948 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18954 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18955 Intent resultData) {
18957 synchronized (this) {
18958 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18960 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18966 public int getLaunchedFromUid(IBinder activityToken) {
18967 ActivityRecord srec;
18968 synchronized (this) {
18969 srec = ActivityRecord.forTokenLocked(activityToken);
18971 if (srec == null) {
18974 return srec.launchedFromUid;
18977 public String getLaunchedFromPackage(IBinder activityToken) {
18978 ActivityRecord srec;
18979 synchronized (this) {
18980 srec = ActivityRecord.forTokenLocked(activityToken);
18982 if (srec == null) {
18985 return srec.launchedFromPackage;
18988 // =========================================================
18989 // LIFETIME MANAGEMENT
18990 // =========================================================
18992 // Returns which broadcast queue the app is the current [or imminent] receiver
18993 // on, or 'null' if the app is not an active broadcast recipient.
18994 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18995 BroadcastRecord r = app.curReceiver;
19000 // It's not the current receiver, but it might be starting up to become one
19001 synchronized (this) {
19002 for (BroadcastQueue queue : mBroadcastQueues) {
19003 r = queue.mPendingBroadcast;
19004 if (r != null && r.curApp == app) {
19005 // found it; report which queue it's in
19014 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19015 int targetUid, ComponentName targetComponent, String targetProcess) {
19016 if (!mTrackingAssociations) {
19019 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19020 = mAssociations.get(targetUid);
19021 if (components == null) {
19022 components = new ArrayMap<>();
19023 mAssociations.put(targetUid, components);
19025 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19026 if (sourceUids == null) {
19027 sourceUids = new SparseArray<>();
19028 components.put(targetComponent, sourceUids);
19030 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19031 if (sourceProcesses == null) {
19032 sourceProcesses = new ArrayMap<>();
19033 sourceUids.put(sourceUid, sourceProcesses);
19035 Association ass = sourceProcesses.get(sourceProcess);
19037 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19039 sourceProcesses.put(sourceProcess, ass);
19043 if (ass.mNesting == 1) {
19044 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19045 ass.mLastState = sourceState;
19050 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19051 ComponentName targetComponent) {
19052 if (!mTrackingAssociations) {
19055 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19056 = mAssociations.get(targetUid);
19057 if (components == null) {
19060 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19061 if (sourceUids == null) {
19064 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19065 if (sourceProcesses == null) {
19068 Association ass = sourceProcesses.get(sourceProcess);
19069 if (ass == null || ass.mNesting <= 0) {
19073 if (ass.mNesting == 0) {
19074 long uptime = SystemClock.uptimeMillis();
19075 ass.mTime += uptime - ass.mStartTime;
19076 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19077 += uptime - ass.mLastStateUptime;
19078 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19082 private void noteUidProcessState(final int uid, final int state) {
19083 mBatteryStatsService.noteUidProcessState(uid, state);
19084 if (mTrackingAssociations) {
19085 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19086 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19087 = mAssociations.valueAt(i1);
19088 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19089 SparseArray<ArrayMap<String, Association>> sourceUids
19090 = targetComponents.valueAt(i2);
19091 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19092 if (sourceProcesses != null) {
19093 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19094 Association ass = sourceProcesses.valueAt(i4);
19095 if (ass.mNesting >= 1) {
19096 // currently associated
19097 long uptime = SystemClock.uptimeMillis();
19098 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19099 += uptime - ass.mLastStateUptime;
19100 ass.mLastState = state;
19101 ass.mLastStateUptime = uptime;
19110 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19111 boolean doingAll, long now) {
19112 if (mAdjSeq == app.adjSeq) {
19113 // This adjustment has already been computed.
19114 return app.curRawAdj;
19117 if (app.thread == null) {
19118 app.adjSeq = mAdjSeq;
19119 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19120 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19121 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19124 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19125 app.adjSource = null;
19126 app.adjTarget = null;
19128 app.cached = false;
19130 final int activitiesSize = app.activities.size();
19132 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19133 // The max adjustment doesn't allow this app to be anything
19134 // below foreground, so it is not worth doing work for it.
19135 app.adjType = "fixed";
19136 app.adjSeq = mAdjSeq;
19137 app.curRawAdj = app.maxAdj;
19138 app.foregroundActivities = false;
19139 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19140 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19141 // System processes can do UI, and when they do we want to have
19142 // them trim their memory after the user leaves the UI. To
19143 // facilitate this, here we need to determine whether or not it
19144 // is currently showing UI.
19145 app.systemNoUi = true;
19146 if (app == TOP_APP) {
19147 app.systemNoUi = false;
19148 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19149 app.adjType = "pers-top-activity";
19150 } else if (activitiesSize > 0) {
19151 for (int j = 0; j < activitiesSize; j++) {
19152 final ActivityRecord r = app.activities.get(j);
19154 app.systemNoUi = false;
19158 if (!app.systemNoUi) {
19159 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19161 return (app.curAdj=app.maxAdj);
19164 app.systemNoUi = false;
19166 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19168 // Determine the importance of the process, starting with most
19169 // important to least, and assign an appropriate OOM adjustment.
19173 boolean foregroundActivities = false;
19174 BroadcastQueue queue;
19175 if (app == TOP_APP) {
19176 // The last app on the list is the foreground app.
19177 adj = ProcessList.FOREGROUND_APP_ADJ;
19178 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19179 app.adjType = "top-activity";
19180 foregroundActivities = true;
19181 procState = PROCESS_STATE_CUR_TOP;
19182 } else if (app.instrumentationClass != null) {
19183 // Don't want to kill running instrumentation.
19184 adj = ProcessList.FOREGROUND_APP_ADJ;
19185 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19186 app.adjType = "instrumentation";
19187 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19188 } else if ((queue = isReceivingBroadcast(app)) != null) {
19189 // An app that is currently receiving a broadcast also
19190 // counts as being in the foreground for OOM killer purposes.
19191 // It's placed in a sched group based on the nature of the
19192 // broadcast as reflected by which queue it's active in.
19193 adj = ProcessList.FOREGROUND_APP_ADJ;
19194 schedGroup = (queue == mFgBroadcastQueue)
19195 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19196 app.adjType = "broadcast";
19197 procState = ActivityManager.PROCESS_STATE_RECEIVER;
19198 } else if (app.executingServices.size() > 0) {
19199 // An app that is currently executing a service callback also
19200 // counts as being in the foreground.
19201 adj = ProcessList.FOREGROUND_APP_ADJ;
19202 schedGroup = app.execServicesFg ?
19203 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19204 app.adjType = "exec-service";
19205 procState = ActivityManager.PROCESS_STATE_SERVICE;
19206 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19208 // As far as we know the process is empty. We may change our mind later.
19209 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19210 // At this point we don't actually know the adjustment. Use the cached adj
19211 // value that the caller wants us to.
19213 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19216 app.adjType = "cch-empty";
19219 // Examine all activities if not already foreground.
19220 if (!foregroundActivities && activitiesSize > 0) {
19221 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19222 for (int j = 0; j < activitiesSize; j++) {
19223 final ActivityRecord r = app.activities.get(j);
19224 if (r.app != app) {
19225 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19226 + " instead of expected " + app);
19227 if (r.app == null || (r.app.uid == app.uid)) {
19228 // Only fix things up when they look sane
19235 // App has a visible activity; only upgrade adjustment.
19236 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19237 adj = ProcessList.VISIBLE_APP_ADJ;
19238 app.adjType = "visible";
19240 if (procState > PROCESS_STATE_CUR_TOP) {
19241 procState = PROCESS_STATE_CUR_TOP;
19243 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19244 app.cached = false;
19246 foregroundActivities = true;
19247 if (r.task != null && minLayer > 0) {
19248 final int layer = r.task.mLayerRank;
19249 if (layer >= 0 && minLayer > layer) {
19254 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19255 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19256 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19257 app.adjType = "pausing";
19259 if (procState > PROCESS_STATE_CUR_TOP) {
19260 procState = PROCESS_STATE_CUR_TOP;
19262 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19263 app.cached = false;
19265 foregroundActivities = true;
19266 } else if (r.state == ActivityState.STOPPING) {
19267 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19268 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19269 app.adjType = "stopping";
19271 // For the process state, we will at this point consider the
19272 // process to be cached. It will be cached either as an activity
19273 // or empty depending on whether the activity is finishing. We do
19274 // this so that we can treat the process as cached for purposes of
19275 // memory trimming (determing current memory level, trim command to
19276 // send to process) since there can be an arbitrary number of stopping
19277 // processes and they should soon all go into the cached state.
19278 if (!r.finishing) {
19279 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19280 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19283 app.cached = false;
19285 foregroundActivities = true;
19287 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19288 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19289 app.adjType = "cch-act";
19293 if (adj == ProcessList.VISIBLE_APP_ADJ) {
19298 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19299 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19300 if (app.foregroundServices) {
19301 // The user is aware of this app, so make it visible.
19302 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19303 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19304 app.cached = false;
19305 app.adjType = "fg-service";
19306 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19307 } else if (app.forcingToForeground != null) {
19308 // The user is aware of this app, so make it visible.
19309 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19310 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19311 app.cached = false;
19312 app.adjType = "force-fg";
19313 app.adjSource = app.forcingToForeground;
19314 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19318 if (app == mHeavyWeightProcess) {
19319 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19320 // We don't want to kill the current heavy-weight process.
19321 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19322 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19323 app.cached = false;
19324 app.adjType = "heavy";
19326 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19327 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19331 if (app == mHomeProcess) {
19332 if (adj > ProcessList.HOME_APP_ADJ) {
19333 // This process is hosting what we currently consider to be the
19334 // home app, so we don't want to let it go into the background.
19335 adj = ProcessList.HOME_APP_ADJ;
19336 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19337 app.cached = false;
19338 app.adjType = "home";
19340 if (procState > ActivityManager.PROCESS_STATE_HOME) {
19341 procState = ActivityManager.PROCESS_STATE_HOME;
19345 if (app == mPreviousProcess && app.activities.size() > 0) {
19346 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19347 // This was the previous process that showed UI to the user.
19348 // We want to try to keep it around more aggressively, to give
19349 // a good experience around switching between two apps.
19350 adj = ProcessList.PREVIOUS_APP_ADJ;
19351 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19352 app.cached = false;
19353 app.adjType = "previous";
19355 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19356 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19360 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19361 + " reason=" + app.adjType);
19363 // By default, we use the computed adjustment. It may be changed if
19364 // there are applications dependent on our services or providers, but
19365 // this gives us a baseline and makes sure we don't get into an
19366 // infinite recursion.
19367 app.adjSeq = mAdjSeq;
19368 app.curRawAdj = adj;
19369 app.hasStartedServices = false;
19371 if (mBackupTarget != null && app == mBackupTarget.app) {
19372 // If possible we want to avoid killing apps while they're being backed up
19373 if (adj > ProcessList.BACKUP_APP_ADJ) {
19374 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19375 adj = ProcessList.BACKUP_APP_ADJ;
19376 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19377 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19379 app.adjType = "backup";
19380 app.cached = false;
19382 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19383 procState = ActivityManager.PROCESS_STATE_BACKUP;
19387 boolean mayBeTop = false;
19389 for (int is = app.services.size()-1;
19390 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19391 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19392 || procState > ActivityManager.PROCESS_STATE_TOP);
19394 ServiceRecord s = app.services.valueAt(is);
19395 if (s.startRequested) {
19396 app.hasStartedServices = true;
19397 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19398 procState = ActivityManager.PROCESS_STATE_SERVICE;
19400 if (app.hasShownUi && app != mHomeProcess) {
19401 // If this process has shown some UI, let it immediately
19402 // go to the LRU list because it may be pretty heavy with
19403 // UI stuff. We'll tag it with a label just to help
19404 // debug and understand what is going on.
19405 if (adj > ProcessList.SERVICE_ADJ) {
19406 app.adjType = "cch-started-ui-services";
19409 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19410 // This service has seen some activity within
19411 // recent memory, so we will keep its process ahead
19412 // of the background processes.
19413 if (adj > ProcessList.SERVICE_ADJ) {
19414 adj = ProcessList.SERVICE_ADJ;
19415 app.adjType = "started-services";
19416 app.cached = false;
19419 // If we have let the service slide into the background
19420 // state, still have some text describing what it is doing
19421 // even though the service no longer has an impact.
19422 if (adj > ProcessList.SERVICE_ADJ) {
19423 app.adjType = "cch-started-services";
19428 for (int conni = s.connections.size()-1;
19429 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19430 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19431 || procState > ActivityManager.PROCESS_STATE_TOP);
19433 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19435 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19436 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19437 || procState > ActivityManager.PROCESS_STATE_TOP);
19439 // XXX should compute this based on the max of
19440 // all connected clients.
19441 ConnectionRecord cr = clist.get(i);
19442 if (cr.binding.client == app) {
19443 // Binding to ourself is not interesting.
19447 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19448 ProcessRecord client = cr.binding.client;
19449 int clientAdj = computeOomAdjLocked(client, cachedAdj,
19450 TOP_APP, doingAll, now);
19451 int clientProcState = client.curProcState;
19452 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19453 // If the other app is cached for any reason, for purposes here
19454 // we are going to consider it empty. The specific cached state
19455 // doesn't propagate except under certain conditions.
19456 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19458 String adjType = null;
19459 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19460 // Not doing bind OOM management, so treat
19461 // this guy more like a started service.
19462 if (app.hasShownUi && app != mHomeProcess) {
19463 // If this process has shown some UI, let it immediately
19464 // go to the LRU list because it may be pretty heavy with
19465 // UI stuff. We'll tag it with a label just to help
19466 // debug and understand what is going on.
19467 if (adj > clientAdj) {
19468 adjType = "cch-bound-ui-services";
19470 app.cached = false;
19472 clientProcState = procState;
19474 if (now >= (s.lastActivity
19475 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19476 // This service has not seen activity within
19477 // recent memory, so allow it to drop to the
19478 // LRU list if there is no other reason to keep
19479 // it around. We'll also tag it with a label just
19480 // to help debug and undertand what is going on.
19481 if (adj > clientAdj) {
19482 adjType = "cch-bound-services";
19488 if (adj > clientAdj) {
19489 // If this process has recently shown UI, and
19490 // the process that is binding to it is less
19491 // important than being visible, then we don't
19492 // care about the binding as much as we care
19493 // about letting this process get into the LRU
19494 // list to be killed and restarted if needed for
19496 if (app.hasShownUi && app != mHomeProcess
19497 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19498 adjType = "cch-bound-ui-services";
19500 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19501 |Context.BIND_IMPORTANT)) != 0) {
19502 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19503 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19504 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19505 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19506 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19507 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19508 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19511 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19512 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19515 if (!client.cached) {
19516 app.cached = false;
19518 adjType = "service";
19521 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19522 // This will treat important bound services identically to
19523 // the top app, which may behave differently than generic
19524 // foreground work.
19525 if (client.curSchedGroup > schedGroup) {
19526 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19527 schedGroup = client.curSchedGroup;
19529 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19532 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19533 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19534 // Special handling of clients who are in the top state.
19535 // We *may* want to consider this process to be in the
19536 // top state as well, but only if there is not another
19537 // reason for it to be running. Being on the top is a
19538 // special state, meaning you are specifically running
19539 // for the current top app. If the process is already
19540 // running in the background for some other reason, it
19541 // is more important to continue considering it to be
19542 // in the background state.
19544 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19546 // Special handling for above-top states (persistent
19547 // processes). These should not bring the current process
19548 // into the top state, since they are not on top. Instead
19549 // give them the best state after that.
19550 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19552 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19553 } else if (mWakefulness
19554 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19555 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19558 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19561 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19566 if (clientProcState <
19567 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19569 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19572 if (procState > clientProcState) {
19573 procState = clientProcState;
19575 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19576 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19577 app.pendingUiClean = true;
19579 if (adjType != null) {
19580 app.adjType = adjType;
19581 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19582 .REASON_SERVICE_IN_USE;
19583 app.adjSource = cr.binding.client;
19584 app.adjSourceProcState = clientProcState;
19585 app.adjTarget = s.name;
19588 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19589 app.treatLikeActivity = true;
19591 final ActivityRecord a = cr.activity;
19592 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19593 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19594 (a.visible || a.state == ActivityState.RESUMED ||
19595 a.state == ActivityState.PAUSING)) {
19596 adj = ProcessList.FOREGROUND_APP_ADJ;
19597 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19598 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19599 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19601 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19604 app.cached = false;
19605 app.adjType = "service";
19606 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19607 .REASON_SERVICE_IN_USE;
19609 app.adjSourceProcState = procState;
19610 app.adjTarget = s.name;
19617 for (int provi = app.pubProviders.size()-1;
19618 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19619 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19620 || procState > ActivityManager.PROCESS_STATE_TOP);
19622 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19623 for (int i = cpr.connections.size()-1;
19624 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19625 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19626 || procState > ActivityManager.PROCESS_STATE_TOP);
19628 ContentProviderConnection conn = cpr.connections.get(i);
19629 ProcessRecord client = conn.client;
19630 if (client == app) {
19631 // Being our own client is not interesting.
19634 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19635 int clientProcState = client.curProcState;
19636 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19637 // If the other app is cached for any reason, for purposes here
19638 // we are going to consider it empty.
19639 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19641 if (adj > clientAdj) {
19642 if (app.hasShownUi && app != mHomeProcess
19643 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19644 app.adjType = "cch-ui-provider";
19646 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19647 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19648 app.adjType = "provider";
19650 app.cached &= client.cached;
19651 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19652 .REASON_PROVIDER_IN_USE;
19653 app.adjSource = client;
19654 app.adjSourceProcState = clientProcState;
19655 app.adjTarget = cpr.name;
19657 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19658 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19659 // Special handling of clients who are in the top state.
19660 // We *may* want to consider this process to be in the
19661 // top state as well, but only if there is not another
19662 // reason for it to be running. Being on the top is a
19663 // special state, meaning you are specifically running
19664 // for the current top app. If the process is already
19665 // running in the background for some other reason, it
19666 // is more important to continue considering it to be
19667 // in the background state.
19669 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19671 // Special handling for above-top states (persistent
19672 // processes). These should not bring the current process
19673 // into the top state, since they are not on top. Instead
19674 // give them the best state after that.
19676 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19679 if (procState > clientProcState) {
19680 procState = clientProcState;
19682 if (client.curSchedGroup > schedGroup) {
19683 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19686 // If the provider has external (non-framework) process
19687 // dependencies, ensure that its adjustment is at least
19688 // FOREGROUND_APP_ADJ.
19689 if (cpr.hasExternalProcessHandles()) {
19690 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19691 adj = ProcessList.FOREGROUND_APP_ADJ;
19692 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19693 app.cached = false;
19694 app.adjType = "provider";
19695 app.adjTarget = cpr.name;
19697 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19698 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19703 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19704 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19705 adj = ProcessList.PREVIOUS_APP_ADJ;
19706 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19707 app.cached = false;
19708 app.adjType = "provider";
19710 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19711 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19715 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19716 // A client of one of our services or providers is in the top state. We
19717 // *may* want to be in the top state, but not if we are already running in
19718 // the background for some other reason. For the decision here, we are going
19719 // to pick out a few specific states that we want to remain in when a client
19720 // is top (states that tend to be longer-term) and otherwise allow it to go
19721 // to the top state.
19722 switch (procState) {
19723 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19724 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19725 case ActivityManager.PROCESS_STATE_SERVICE:
19726 // These all are longer-term states, so pull them up to the top
19727 // of the background states, but not all the way to the top state.
19728 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19731 // Otherwise, top is a better choice, so take it.
19732 procState = ActivityManager.PROCESS_STATE_TOP;
19737 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19738 if (app.hasClientActivities) {
19739 // This is a cached process, but with client activities. Mark it so.
19740 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19741 app.adjType = "cch-client-act";
19742 } else if (app.treatLikeActivity) {
19743 // This is a cached process, but somebody wants us to treat it like it has
19744 // an activity, okay!
19745 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19746 app.adjType = "cch-as-act";
19750 if (adj == ProcessList.SERVICE_ADJ) {
19752 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19753 mNewNumServiceProcs++;
19754 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19755 if (!app.serviceb) {
19756 // This service isn't far enough down on the LRU list to
19757 // normally be a B service, but if we are low on RAM and it
19758 // is large we want to force it down since we would prefer to
19759 // keep launcher over it.
19760 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19761 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19762 app.serviceHighRam = true;
19763 app.serviceb = true;
19764 //Slog.i(TAG, "ADJ " + app + " high ram!");
19766 mNewNumAServiceProcs++;
19767 //Slog.i(TAG, "ADJ " + app + " not high ram!");
19770 app.serviceHighRam = false;
19773 if (app.serviceb) {
19774 adj = ProcessList.SERVICE_B_ADJ;
19778 app.curRawAdj = adj;
19780 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19781 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19782 if (adj > app.maxAdj) {
19784 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19785 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19789 // Do final modification to adj. Everything we do between here and applying
19790 // the final setAdj must be done in this function, because we will also use
19791 // it when computing the final cached adj later. Note that we don't need to
19792 // worry about this for max adj above, since max adj will always be used to
19793 // keep it out of the cached vaues.
19794 app.curAdj = app.modifyRawOomAdj(adj);
19795 app.curSchedGroup = schedGroup;
19796 app.curProcState = procState;
19797 app.foregroundActivities = foregroundActivities;
19799 return app.curRawAdj;
19803 * Record new PSS sample for a process.
19805 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19807 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19809 proc.lastPssTime = now;
19810 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19811 if (DEBUG_PSS) Slog.d(TAG_PSS,
19812 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19813 + " state=" + ProcessList.makeProcStateString(procState));
19814 if (proc.initialIdlePss == 0) {
19815 proc.initialIdlePss = pss;
19817 proc.lastPss = pss;
19818 proc.lastSwapPss = swapPss;
19819 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19820 proc.lastCachedPss = pss;
19821 proc.lastCachedSwapPss = swapPss;
19824 final SparseArray<Pair<Long, String>> watchUids
19825 = mMemWatchProcesses.getMap().get(proc.processName);
19827 if (watchUids != null) {
19828 Pair<Long, String> val = watchUids.get(proc.uid);
19830 val = watchUids.get(0);
19836 if (check != null) {
19837 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19838 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19839 if (!isDebuggable) {
19840 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19841 isDebuggable = true;
19844 if (isDebuggable) {
19845 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19846 final ProcessRecord myProc = proc;
19847 final File heapdumpFile = DumpHeapProvider.getJavaFile();
19848 mMemWatchDumpProcName = proc.processName;
19849 mMemWatchDumpFile = heapdumpFile.toString();
19850 mMemWatchDumpPid = proc.pid;
19851 mMemWatchDumpUid = proc.uid;
19852 BackgroundThread.getHandler().post(new Runnable() {
19854 public void run() {
19855 revokeUriPermission(ActivityThread.currentActivityThread()
19856 .getApplicationThread(),
19857 DumpHeapActivity.JAVA_URI,
19858 Intent.FLAG_GRANT_READ_URI_PERMISSION
19859 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19860 UserHandle.myUserId());
19861 ParcelFileDescriptor fd = null;
19863 heapdumpFile.delete();
19864 fd = ParcelFileDescriptor.open(heapdumpFile,
19865 ParcelFileDescriptor.MODE_CREATE |
19866 ParcelFileDescriptor.MODE_TRUNCATE |
19867 ParcelFileDescriptor.MODE_WRITE_ONLY |
19868 ParcelFileDescriptor.MODE_APPEND);
19869 IApplicationThread thread = myProc.thread;
19870 if (thread != null) {
19872 if (DEBUG_PSS) Slog.d(TAG_PSS,
19873 "Requesting dump heap from "
19874 + myProc + " to " + heapdumpFile);
19875 thread.dumpHeap(true, heapdumpFile.toString(), fd);
19876 } catch (RemoteException e) {
19879 } catch (FileNotFoundException e) {
19880 e.printStackTrace();
19885 } catch (IOException e) {
19892 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19893 + ", but debugging not enabled");
19900 * Schedule PSS collection of a process.
19902 void requestPssLocked(ProcessRecord proc, int procState) {
19903 if (mPendingPssProcesses.contains(proc)) {
19906 if (mPendingPssProcesses.size() == 0) {
19907 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19909 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19910 proc.pssProcState = procState;
19911 mPendingPssProcesses.add(proc);
19915 * Schedule PSS collection of all processes.
19917 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19919 if (now < (mLastFullPssTime +
19920 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19924 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
19925 mLastFullPssTime = now;
19926 mFullPssPending = true;
19927 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19928 mPendingPssProcesses.clear();
19929 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19930 ProcessRecord app = mLruProcesses.get(i);
19931 if (app.thread == null
19932 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19935 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19936 app.pssProcState = app.setProcState;
19937 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19938 mTestPssMode, isSleepingLocked(), now);
19939 mPendingPssProcesses.add(app);
19942 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19945 public void setTestPssMode(boolean enabled) {
19946 synchronized (this) {
19947 mTestPssMode = enabled;
19949 // Whenever we enable the mode, we want to take a snapshot all of current
19950 // process mem use.
19951 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19957 * Ask a given process to GC right now.
19959 final void performAppGcLocked(ProcessRecord app) {
19961 app.lastRequestedGc = SystemClock.uptimeMillis();
19962 if (app.thread != null) {
19963 if (app.reportLowMemory) {
19964 app.reportLowMemory = false;
19965 app.thread.scheduleLowMemory();
19967 app.thread.processInBackground();
19970 } catch (Exception e) {
19976 * Returns true if things are idle enough to perform GCs.
19978 private final boolean canGcNowLocked() {
19979 boolean processingBroadcasts = false;
19980 for (BroadcastQueue q : mBroadcastQueues) {
19981 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19982 processingBroadcasts = true;
19985 return !processingBroadcasts
19986 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19990 * Perform GCs on all processes that are waiting for it, but only
19991 * if things are idle.
19993 final void performAppGcsLocked() {
19994 final int N = mProcessesToGc.size();
19998 if (canGcNowLocked()) {
19999 while (mProcessesToGc.size() > 0) {
20000 ProcessRecord proc = mProcessesToGc.remove(0);
20001 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20002 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20003 <= SystemClock.uptimeMillis()) {
20004 // To avoid spamming the system, we will GC processes one
20005 // at a time, waiting a few seconds between each.
20006 performAppGcLocked(proc);
20007 scheduleAppGcsLocked();
20010 // It hasn't been long enough since we last GCed this
20011 // process... put it in the list to wait for its time.
20012 addProcessToGcListLocked(proc);
20018 scheduleAppGcsLocked();
20023 * If all looks good, perform GCs on all processes waiting for them.
20025 final void performAppGcsIfAppropriateLocked() {
20026 if (canGcNowLocked()) {
20027 performAppGcsLocked();
20030 // Still not idle, wait some more.
20031 scheduleAppGcsLocked();
20035 * Schedule the execution of all pending app GCs.
20037 final void scheduleAppGcsLocked() {
20038 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20040 if (mProcessesToGc.size() > 0) {
20041 // Schedule a GC for the time to the next process.
20042 ProcessRecord proc = mProcessesToGc.get(0);
20043 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20045 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20046 long now = SystemClock.uptimeMillis();
20047 if (when < (now+GC_TIMEOUT)) {
20048 when = now + GC_TIMEOUT;
20050 mHandler.sendMessageAtTime(msg, when);
20055 * Add a process to the array of processes waiting to be GCed. Keeps the
20056 * list in sorted order by the last GC time. The process can't already be
20059 final void addProcessToGcListLocked(ProcessRecord proc) {
20060 boolean added = false;
20061 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20062 if (mProcessesToGc.get(i).lastRequestedGc <
20063 proc.lastRequestedGc) {
20065 mProcessesToGc.add(i+1, proc);
20070 mProcessesToGc.add(0, proc);
20075 * Set up to ask a process to GC itself. This will either do it
20076 * immediately, or put it on the list of processes to gc the next
20077 * time things are idle.
20079 final void scheduleAppGcLocked(ProcessRecord app) {
20080 long now = SystemClock.uptimeMillis();
20081 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20084 if (!mProcessesToGc.contains(app)) {
20085 addProcessToGcListLocked(app);
20086 scheduleAppGcsLocked();
20090 final void checkExcessivePowerUsageLocked(boolean doKills) {
20091 updateCpuStatsNow();
20093 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20094 boolean doWakeKills = doKills;
20095 boolean doCpuKills = doKills;
20096 if (mLastPowerCheckRealtime == 0) {
20097 doWakeKills = false;
20099 if (mLastPowerCheckUptime == 0) {
20100 doCpuKills = false;
20102 if (stats.isScreenOn()) {
20103 doWakeKills = false;
20105 final long curRealtime = SystemClock.elapsedRealtime();
20106 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20107 final long curUptime = SystemClock.uptimeMillis();
20108 final long uptimeSince = curUptime - mLastPowerCheckUptime;
20109 mLastPowerCheckRealtime = curRealtime;
20110 mLastPowerCheckUptime = curUptime;
20111 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20112 doWakeKills = false;
20114 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20115 doCpuKills = false;
20117 int i = mLruProcesses.size();
20120 ProcessRecord app = mLruProcesses.get(i);
20121 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20123 synchronized (stats) {
20124 wtime = stats.getProcessWakeTime(app.info.uid,
20125 app.pid, curRealtime);
20127 long wtimeUsed = wtime - app.lastWakeTime;
20128 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20130 StringBuilder sb = new StringBuilder(128);
20131 sb.append("Wake for ");
20132 app.toShortString(sb);
20133 sb.append(": over ");
20134 TimeUtils.formatDuration(realtimeSince, sb);
20135 sb.append(" used ");
20136 TimeUtils.formatDuration(wtimeUsed, sb);
20138 sb.append((wtimeUsed*100)/realtimeSince);
20140 Slog.i(TAG_POWER, sb.toString());
20142 sb.append("CPU for ");
20143 app.toShortString(sb);
20144 sb.append(": over ");
20145 TimeUtils.formatDuration(uptimeSince, sb);
20146 sb.append(" used ");
20147 TimeUtils.formatDuration(cputimeUsed, sb);
20149 sb.append((cputimeUsed*100)/uptimeSince);
20151 Slog.i(TAG_POWER, sb.toString());
20153 // If a process has held a wake lock for more
20154 // than 50% of the time during this period,
20155 // that sounds bad. Kill!
20156 if (doWakeKills && realtimeSince > 0
20157 && ((wtimeUsed*100)/realtimeSince) >= 50) {
20158 synchronized (stats) {
20159 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20160 realtimeSince, wtimeUsed);
20162 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20163 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20164 } else if (doCpuKills && uptimeSince > 0
20165 && ((cputimeUsed*100)/uptimeSince) >= 25) {
20166 synchronized (stats) {
20167 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20168 uptimeSince, cputimeUsed);
20170 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20171 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20173 app.lastWakeTime = wtime;
20174 app.lastCpuTime = app.curCpuTime;
20180 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20182 boolean success = true;
20184 if (app.curRawAdj != app.setRawAdj) {
20185 app.setRawAdj = app.curRawAdj;
20190 if (app.curAdj != app.setAdj) {
20191 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20192 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20193 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20195 app.setAdj = app.curAdj;
20196 app.verifiedAdj = ProcessList.INVALID_ADJ;
20199 if (app.setSchedGroup != app.curSchedGroup) {
20200 app.setSchedGroup = app.curSchedGroup;
20201 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20202 "Setting sched group of " + app.processName
20203 + " to " + app.curSchedGroup);
20204 if (app.waitingToKill != null && app.curReceiver == null
20205 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20206 app.kill(app.waitingToKill, true);
20210 switch (app.curSchedGroup) {
20211 case ProcessList.SCHED_GROUP_BACKGROUND:
20212 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20214 case ProcessList.SCHED_GROUP_TOP_APP:
20215 processGroup = Process.THREAD_GROUP_TOP_APP;
20218 processGroup = Process.THREAD_GROUP_DEFAULT;
20222 long oldId = Binder.clearCallingIdentity();
20224 Process.setProcessGroup(app.pid, processGroup);
20225 } catch (Exception e) {
20226 Slog.w(TAG, "Failed setting process group of " + app.pid
20227 + " to " + app.curSchedGroup);
20228 e.printStackTrace();
20230 Binder.restoreCallingIdentity(oldId);
20233 if (app.thread != null) {
20235 app.thread.setSchedulingGroup(processGroup);
20236 } catch (RemoteException e) {
20242 if (app.repForegroundActivities != app.foregroundActivities) {
20243 app.repForegroundActivities = app.foregroundActivities;
20244 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20246 if (app.repProcState != app.curProcState) {
20247 app.repProcState = app.curProcState;
20248 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20249 if (app.thread != null) {
20252 //RuntimeException h = new RuntimeException("here");
20253 Slog.i(TAG, "Sending new process state " + app.repProcState
20254 + " to " + app /*, h*/);
20256 app.thread.setProcessState(app.repProcState);
20257 } catch (RemoteException e) {
20261 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20262 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20263 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20264 // Experimental code to more aggressively collect pss while
20265 // running test... the problem is that this tends to collect
20266 // the data right when a process is transitioning between process
20267 // states, which well tend to give noisy data.
20268 long start = SystemClock.uptimeMillis();
20269 long pss = Debug.getPss(app.pid, mTmpLong, null);
20270 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20271 mPendingPssProcesses.remove(app);
20272 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20273 + " to " + app.curProcState + ": "
20274 + (SystemClock.uptimeMillis()-start) + "ms");
20276 app.lastStateTime = now;
20277 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20278 mTestPssMode, isSleepingLocked(), now);
20279 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20280 + ProcessList.makeProcStateString(app.setProcState) + " to "
20281 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20282 + (app.nextPssTime-now) + ": " + app);
20284 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20285 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20287 requestPssLocked(app, app.setProcState);
20288 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20289 mTestPssMode, isSleepingLocked(), now);
20290 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20291 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20293 if (app.setProcState != app.curProcState) {
20294 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20295 "Proc state change of " + app.processName
20296 + " to " + app.curProcState);
20297 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20298 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20299 if (setImportant && !curImportant) {
20300 // This app is no longer something we consider important enough to allow to
20301 // use arbitrary amounts of battery power. Note
20302 // its current wake lock time to later know to kill it if
20303 // it is not behaving well.
20304 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20305 synchronized (stats) {
20306 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20307 app.pid, nowElapsed);
20309 app.lastCpuTime = app.curCpuTime;
20312 // Inform UsageStats of important process state change
20313 // Must be called before updating setProcState
20314 maybeUpdateUsageStatsLocked(app, nowElapsed);
20316 app.setProcState = app.curProcState;
20317 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20318 app.notCachedSinceIdle = false;
20321 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20323 app.procStateChanged = true;
20325 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20326 > USAGE_STATS_INTERACTION_INTERVAL) {
20327 // For apps that sit around for a long time in the interactive state, we need
20328 // to report this at least once a day so they don't go idle.
20329 maybeUpdateUsageStatsLocked(app, nowElapsed);
20332 if (changes != 0) {
20333 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20334 "Changes in " + app + ": " + changes);
20335 int i = mPendingProcessChanges.size()-1;
20336 ProcessChangeItem item = null;
20338 item = mPendingProcessChanges.get(i);
20339 if (item.pid == app.pid) {
20340 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20341 "Re-using existing item: " + item);
20347 // No existing item in pending changes; need a new one.
20348 final int NA = mAvailProcessChanges.size();
20350 item = mAvailProcessChanges.remove(NA-1);
20351 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20352 "Retrieving available item: " + item);
20354 item = new ProcessChangeItem();
20355 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20356 "Allocating new item: " + item);
20359 item.pid = app.pid;
20360 item.uid = app.info.uid;
20361 if (mPendingProcessChanges.size() == 0) {
20362 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20363 "*** Enqueueing dispatch processes changed!");
20364 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20366 mPendingProcessChanges.add(item);
20368 item.changes |= changes;
20369 item.processState = app.repProcState;
20370 item.foregroundActivities = app.repForegroundActivities;
20371 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20372 "Item " + Integer.toHexString(System.identityHashCode(item))
20373 + " " + app.toShortString() + ": changes=" + item.changes
20374 + " procState=" + item.processState
20375 + " foreground=" + item.foregroundActivities
20376 + " type=" + app.adjType + " source=" + app.adjSource
20377 + " target=" + app.adjTarget);
20383 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20384 final UidRecord.ChangeItem pendingChange;
20385 if (uidRec == null || uidRec.pendingChange == null) {
20386 if (mPendingUidChanges.size() == 0) {
20387 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20388 "*** Enqueueing dispatch uid changed!");
20389 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20391 final int NA = mAvailUidChanges.size();
20393 pendingChange = mAvailUidChanges.remove(NA-1);
20394 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20395 "Retrieving available item: " + pendingChange);
20397 pendingChange = new UidRecord.ChangeItem();
20398 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20399 "Allocating new item: " + pendingChange);
20401 if (uidRec != null) {
20402 uidRec.pendingChange = pendingChange;
20403 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20404 // If this uid is going away, and we haven't yet reported it is gone,
20406 change = UidRecord.CHANGE_GONE_IDLE;
20408 } else if (uid < 0) {
20409 throw new IllegalArgumentException("No UidRecord or uid");
20411 pendingChange.uidRecord = uidRec;
20412 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20413 mPendingUidChanges.add(pendingChange);
20415 pendingChange = uidRec.pendingChange;
20416 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20417 change = UidRecord.CHANGE_GONE_IDLE;
20420 pendingChange.change = change;
20421 pendingChange.processState = uidRec != null
20422 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20425 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20426 String authority) {
20427 if (app == null) return;
20428 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20429 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20430 if (userState == null) return;
20431 final long now = SystemClock.elapsedRealtime();
20432 Long lastReported = userState.mProviderLastReportedFg.get(authority);
20433 if (lastReported == null || lastReported < now - 60 * 1000L) {
20434 mUsageStatsService.reportContentProviderUsage(
20435 authority, providerPkgName, app.userId);
20436 userState.mProviderLastReportedFg.put(authority, now);
20441 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20442 if (DEBUG_USAGE_STATS) {
20443 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20444 + "] state changes: old = " + app.setProcState + ", new = "
20445 + app.curProcState);
20447 if (mUsageStatsService == null) {
20450 boolean isInteraction;
20451 // To avoid some abuse patterns, we are going to be careful about what we consider
20452 // to be an app interaction. Being the top activity doesn't count while the display
20453 // is sleeping, nor do short foreground services.
20454 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20455 isInteraction = true;
20456 app.fgInteractionTime = 0;
20457 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20458 if (app.fgInteractionTime == 0) {
20459 app.fgInteractionTime = nowElapsed;
20460 isInteraction = false;
20462 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20465 isInteraction = app.curProcState
20466 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20467 app.fgInteractionTime = 0;
20469 if (isInteraction && (!app.reportedInteraction
20470 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20471 app.interactionEventTime = nowElapsed;
20472 String[] packages = app.getPackageList();
20473 if (packages != null) {
20474 for (int i = 0; i < packages.length; i++) {
20475 mUsageStatsService.reportEvent(packages[i], app.userId,
20476 UsageEvents.Event.SYSTEM_INTERACTION);
20480 app.reportedInteraction = isInteraction;
20481 if (!isInteraction) {
20482 app.interactionEventTime = 0;
20486 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20487 if (proc.thread != null) {
20488 if (proc.baseProcessTracker != null) {
20489 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20494 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20495 ProcessRecord TOP_APP, boolean doingAll, long now) {
20496 if (app.thread == null) {
20500 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20502 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20505 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20507 if (isForeground != proc.foregroundServices) {
20508 proc.foregroundServices = isForeground;
20509 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20511 if (isForeground) {
20512 if (curProcs == null) {
20513 curProcs = new ArrayList<ProcessRecord>();
20514 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20516 if (!curProcs.contains(proc)) {
20517 curProcs.add(proc);
20518 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20519 proc.info.packageName, proc.info.uid);
20522 if (curProcs != null) {
20523 if (curProcs.remove(proc)) {
20524 mBatteryStatsService.noteEvent(
20525 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20526 proc.info.packageName, proc.info.uid);
20527 if (curProcs.size() <= 0) {
20528 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20534 updateOomAdjLocked();
20539 private final ActivityRecord resumedAppLocked() {
20540 ActivityRecord act = mStackSupervisor.resumedAppLocked();
20544 pkg = act.packageName;
20545 uid = act.info.applicationInfo.uid;
20550 // Has the UID or resumed package name changed?
20551 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20552 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20553 if (mCurResumedPackage != null) {
20554 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20555 mCurResumedPackage, mCurResumedUid);
20557 mCurResumedPackage = pkg;
20558 mCurResumedUid = uid;
20559 if (mCurResumedPackage != null) {
20560 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20561 mCurResumedPackage, mCurResumedUid);
20567 final boolean updateOomAdjLocked(ProcessRecord app) {
20568 final ActivityRecord TOP_ACT = resumedAppLocked();
20569 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20570 final boolean wasCached = app.cached;
20574 // This is the desired cached adjusment we want to tell it to use.
20575 // If our app is currently cached, we know it, and that is it. Otherwise,
20576 // we don't know it yet, and it needs to now be cached we will then
20577 // need to do a complete oom adj.
20578 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20579 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20580 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20581 SystemClock.uptimeMillis());
20582 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20583 // Changed to/from cached state, so apps after it in the LRU
20584 // list may also be changed.
20585 updateOomAdjLocked();
20590 final void updateOomAdjLocked() {
20591 final ActivityRecord TOP_ACT = resumedAppLocked();
20592 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20593 final long now = SystemClock.uptimeMillis();
20594 final long nowElapsed = SystemClock.elapsedRealtime();
20595 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20596 final int N = mLruProcesses.size();
20599 RuntimeException e = new RuntimeException();
20600 e.fillInStackTrace();
20601 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20604 // Reset state in all uid records.
20605 for (int i=mActiveUids.size()-1; i>=0; i--) {
20606 final UidRecord uidRec = mActiveUids.valueAt(i);
20607 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20608 "Starting update of " + uidRec);
20612 mStackSupervisor.rankTaskLayersIfNeeded();
20615 mNewNumServiceProcs = 0;
20616 mNewNumAServiceProcs = 0;
20618 final int emptyProcessLimit;
20619 final int cachedProcessLimit;
20620 if (mProcessLimit <= 0) {
20621 emptyProcessLimit = cachedProcessLimit = 0;
20622 } else if (mProcessLimit == 1) {
20623 emptyProcessLimit = 1;
20624 cachedProcessLimit = 0;
20626 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20627 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20630 // Let's determine how many processes we have running vs.
20631 // how many slots we have for background processes; we may want
20632 // to put multiple processes in a slot of there are enough of
20634 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20635 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20636 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20637 if (numEmptyProcs > cachedProcessLimit) {
20638 // If there are more empty processes than our limit on cached
20639 // processes, then use the cached process limit for the factor.
20640 // This ensures that the really old empty processes get pushed
20641 // down to the bottom, so if we are running low on memory we will
20642 // have a better chance at keeping around more cached processes
20643 // instead of a gazillion empty processes.
20644 numEmptyProcs = cachedProcessLimit;
20646 int emptyFactor = numEmptyProcs/numSlots;
20647 if (emptyFactor < 1) emptyFactor = 1;
20648 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20649 if (cachedFactor < 1) cachedFactor = 1;
20650 int stepCached = 0;
20654 int numTrimming = 0;
20656 mNumNonCachedProcs = 0;
20657 mNumCachedHiddenProcs = 0;
20659 // First update the OOM adjustment for each of the
20660 // application processes based on their current state.
20661 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20662 int nextCachedAdj = curCachedAdj+1;
20663 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20664 int nextEmptyAdj = curEmptyAdj+2;
20665 for (int i=N-1; i>=0; i--) {
20666 ProcessRecord app = mLruProcesses.get(i);
20667 if (!app.killedByAm && app.thread != null) {
20668 app.procStateChanged = false;
20669 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20671 // If we haven't yet assigned the final cached adj
20672 // to the process, do that now.
20673 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20674 switch (app.curProcState) {
20675 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20676 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20677 // This process is a cached process holding activities...
20678 // assign it the next cached value for that type, and then
20679 // step that cached level.
20680 app.curRawAdj = curCachedAdj;
20681 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20682 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20683 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20685 if (curCachedAdj != nextCachedAdj) {
20687 if (stepCached >= cachedFactor) {
20689 curCachedAdj = nextCachedAdj;
20690 nextCachedAdj += 2;
20691 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20692 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20698 // For everything else, assign next empty cached process
20699 // level and bump that up. Note that this means that
20700 // long-running services that have dropped down to the
20701 // cached level will be treated as empty (since their process
20702 // state is still as a service), which is what we want.
20703 app.curRawAdj = curEmptyAdj;
20704 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20705 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20706 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20708 if (curEmptyAdj != nextEmptyAdj) {
20710 if (stepEmpty >= emptyFactor) {
20712 curEmptyAdj = nextEmptyAdj;
20714 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20715 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20723 applyOomAdjLocked(app, true, now, nowElapsed);
20725 // Count the number of process types.
20726 switch (app.curProcState) {
20727 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20728 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20729 mNumCachedHiddenProcs++;
20731 if (numCached > cachedProcessLimit) {
20732 app.kill("cached #" + numCached, true);
20735 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20736 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20737 && app.lastActivityTime < oldTime) {
20738 app.kill("empty for "
20739 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20740 / 1000) + "s", true);
20743 if (numEmpty > emptyProcessLimit) {
20744 app.kill("empty #" + numEmpty, true);
20749 mNumNonCachedProcs++;
20753 if (app.isolated && app.services.size() <= 0) {
20754 // If this is an isolated process, and there are no
20755 // services running in it, then the process is no longer
20756 // needed. We agressively kill these because we can by
20757 // definition not re-use the same process again, and it is
20758 // good to avoid having whatever code was running in them
20759 // left sitting around after no longer needed.
20760 app.kill("isolated not needed", true);
20762 // Keeping this process, update its uid.
20763 final UidRecord uidRec = app.uidRecord;
20764 if (uidRec != null && uidRec.curProcState > app.curProcState) {
20765 uidRec.curProcState = app.curProcState;
20769 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20770 && !app.killedByAm) {
20776 mNumServiceProcs = mNewNumServiceProcs;
20778 // Now determine the memory trimming level of background processes.
20779 // Unfortunately we need to start at the back of the list to do this
20780 // properly. We only do this if the number of background apps we
20781 // are managing to keep around is less than half the maximum we desire;
20782 // if we are keeping a good number around, we'll let them use whatever
20783 // memory they want.
20784 final int numCachedAndEmpty = numCached + numEmpty;
20786 if (numCached <= ProcessList.TRIM_CACHED_APPS
20787 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20788 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20789 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20790 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20791 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20793 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20796 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20798 // We always allow the memory level to go up (better). We only allow it to go
20799 // down if we are in a state where that is allowed, *and* the total number of processes
20800 // has gone down since last time.
20801 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20802 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20803 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20804 if (memFactor > mLastMemoryLevel) {
20805 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20806 memFactor = mLastMemoryLevel;
20807 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20810 if (memFactor != mLastMemoryLevel) {
20811 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20813 mLastMemoryLevel = memFactor;
20814 mLastNumProcesses = mLruProcesses.size();
20815 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20816 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20817 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20818 if (mLowRamStartTime == 0) {
20819 mLowRamStartTime = now;
20823 switch (memFactor) {
20824 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20825 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20827 case ProcessStats.ADJ_MEM_FACTOR_LOW:
20828 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20831 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20834 int factor = numTrimming/3;
20836 if (mHomeProcess != null) minFactor++;
20837 if (mPreviousProcess != null) minFactor++;
20838 if (factor < minFactor) factor = minFactor;
20839 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20840 for (int i=N-1; i>=0; i--) {
20841 ProcessRecord app = mLruProcesses.get(i);
20842 if (allChanged || app.procStateChanged) {
20843 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20844 app.procStateChanged = false;
20846 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20847 && !app.killedByAm) {
20848 if (app.trimMemoryLevel < curLevel && app.thread != null) {
20850 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20851 "Trimming memory of " + app.processName + " to " + curLevel);
20852 app.thread.scheduleTrimMemory(curLevel);
20853 } catch (RemoteException e) {
20856 // For now we won't do this; our memory trimming seems
20857 // to be good enough at this point that destroying
20858 // activities causes more harm than good.
20859 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20860 && app != mHomeProcess && app != mPreviousProcess) {
20861 // Need to do this on its own message because the stack may not
20862 // be in a consistent state at this point.
20863 // For these apps we will also finish their activities
20864 // to help them free memory.
20865 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20869 app.trimMemoryLevel = curLevel;
20871 if (step >= factor) {
20873 switch (curLevel) {
20874 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20875 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20877 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20878 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20882 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20883 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20884 && app.thread != null) {
20886 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20887 "Trimming memory of heavy-weight " + app.processName
20888 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20889 app.thread.scheduleTrimMemory(
20890 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20891 } catch (RemoteException e) {
20894 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20896 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20897 || app.systemNoUi) && app.pendingUiClean) {
20898 // If this application is now in the background and it
20899 // had done UI, then give it the special trim level to
20900 // have it free UI resources.
20901 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20902 if (app.trimMemoryLevel < level && app.thread != null) {
20904 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20905 "Trimming memory of bg-ui " + app.processName
20907 app.thread.scheduleTrimMemory(level);
20908 } catch (RemoteException e) {
20911 app.pendingUiClean = false;
20913 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20915 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20916 "Trimming memory of fg " + app.processName
20917 + " to " + fgTrimLevel);
20918 app.thread.scheduleTrimMemory(fgTrimLevel);
20919 } catch (RemoteException e) {
20922 app.trimMemoryLevel = fgTrimLevel;
20926 if (mLowRamStartTime != 0) {
20927 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20928 mLowRamStartTime = 0;
20930 for (int i=N-1; i>=0; i--) {
20931 ProcessRecord app = mLruProcesses.get(i);
20932 if (allChanged || app.procStateChanged) {
20933 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20934 app.procStateChanged = false;
20936 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20937 || app.systemNoUi) && app.pendingUiClean) {
20938 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20939 && app.thread != null) {
20941 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20942 "Trimming memory of ui hidden " + app.processName
20943 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20944 app.thread.scheduleTrimMemory(
20945 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20946 } catch (RemoteException e) {
20949 app.pendingUiClean = false;
20951 app.trimMemoryLevel = 0;
20955 if (mAlwaysFinishActivities) {
20956 // Need to do this on its own message because the stack may not
20957 // be in a consistent state at this point.
20958 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20962 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20965 // Update from any uid changes.
20966 for (int i=mActiveUids.size()-1; i>=0; i--) {
20967 final UidRecord uidRec = mActiveUids.valueAt(i);
20968 int uidChange = UidRecord.CHANGE_PROCSTATE;
20969 if (uidRec.setProcState != uidRec.curProcState) {
20970 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20971 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20972 + " to " + uidRec.curProcState);
20973 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20974 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20975 uidRec.lastBackgroundTime = nowElapsed;
20976 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20977 // Note: the background settle time is in elapsed realtime, while
20978 // the handler time base is uptime. All this means is that we may
20979 // stop background uids later than we had intended, but that only
20980 // happens because the device was sleeping so we are okay anyway.
20981 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20986 uidChange = UidRecord.CHANGE_ACTIVE;
20987 uidRec.idle = false;
20989 uidRec.lastBackgroundTime = 0;
20991 uidRec.setProcState = uidRec.curProcState;
20992 enqueueUidChangeLocked(uidRec, -1, uidChange);
20993 noteUidProcessState(uidRec.uid, uidRec.curProcState);
20997 if (mProcessStats.shouldWriteNowLocked(now)) {
20998 mHandler.post(new Runnable() {
20999 @Override public void run() {
21000 synchronized (ActivityManagerService.this) {
21001 mProcessStats.writeStateAsyncLocked();
21007 if (DEBUG_OOM_ADJ) {
21008 final long duration = SystemClock.uptimeMillis() - now;
21010 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21011 new RuntimeException("here").fillInStackTrace());
21013 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21018 final void idleUids() {
21019 synchronized (this) {
21020 final long nowElapsed = SystemClock.elapsedRealtime();
21021 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21023 for (int i=mActiveUids.size()-1; i>=0; i--) {
21024 final UidRecord uidRec = mActiveUids.valueAt(i);
21025 final long bgTime = uidRec.lastBackgroundTime;
21026 if (bgTime > 0 && !uidRec.idle) {
21027 if (bgTime <= maxBgTime) {
21028 uidRec.idle = true;
21029 doStopUidLocked(uidRec.uid, uidRec);
21031 if (nextTime == 0 || nextTime > bgTime) {
21037 if (nextTime > 0) {
21038 mHandler.removeMessages(IDLE_UIDS_MSG);
21039 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21040 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21045 final void runInBackgroundDisabled(int uid) {
21046 synchronized (this) {
21047 UidRecord uidRec = mActiveUids.get(uid);
21048 if (uidRec != null) {
21049 // This uid is actually running... should it be considered background now?
21051 doStopUidLocked(uidRec.uid, uidRec);
21054 // This uid isn't actually running... still send a report about it being "stopped".
21055 doStopUidLocked(uid, null);
21060 final void doStopUidLocked(int uid, final UidRecord uidRec) {
21061 mServices.stopInBackgroundLocked(uid);
21062 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21065 final void trimApplications() {
21066 synchronized (this) {
21069 // First remove any unused application processes whose package
21070 // has been removed.
21071 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21072 final ProcessRecord app = mRemovedProcesses.get(i);
21073 if (app.activities.size() == 0
21074 && app.curReceiver == null && app.services.size() == 0) {
21076 TAG, "Exiting empty application process "
21077 + app.toShortString() + " ("
21078 + (app.thread != null ? app.thread.asBinder() : null)
21080 if (app.pid > 0 && app.pid != MY_PID) {
21081 app.kill("empty", false);
21084 app.thread.scheduleExit();
21085 } catch (Exception e) {
21086 // Ignore exceptions.
21089 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21090 mRemovedProcesses.remove(i);
21092 if (app.persistent) {
21093 addAppLocked(app.info, false, null /* ABI override */);
21098 // Now update the oom adj for all processes.
21099 updateOomAdjLocked();
21103 /** This method sends the specified signal to each of the persistent apps */
21104 public void signalPersistentProcesses(int sig) throws RemoteException {
21105 if (sig != Process.SIGNAL_USR1) {
21106 throw new SecurityException("Only SIGNAL_USR1 is allowed");
21109 synchronized (this) {
21110 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21111 != PackageManager.PERMISSION_GRANTED) {
21112 throw new SecurityException("Requires permission "
21113 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21116 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21117 ProcessRecord r = mLruProcesses.get(i);
21118 if (r.thread != null && r.persistent) {
21119 Process.sendSignal(r.pid, sig);
21125 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21126 if (proc == null || proc == mProfileProc) {
21127 proc = mProfileProc;
21128 profileType = mProfileType;
21129 clearProfilerLocked();
21131 if (proc == null) {
21135 proc.thread.profilerControl(false, null, profileType);
21136 } catch (RemoteException e) {
21137 throw new IllegalStateException("Process disappeared");
21141 private void clearProfilerLocked() {
21142 if (mProfileFd != null) {
21144 mProfileFd.close();
21145 } catch (IOException e) {
21148 mProfileApp = null;
21149 mProfileProc = null;
21150 mProfileFile = null;
21152 mAutoStopProfiler = false;
21153 mSamplingInterval = 0;
21156 public boolean profileControl(String process, int userId, boolean start,
21157 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21160 synchronized (this) {
21161 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21162 // its own permission.
21163 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21164 != PackageManager.PERMISSION_GRANTED) {
21165 throw new SecurityException("Requires permission "
21166 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21169 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21170 throw new IllegalArgumentException("null profile info or fd");
21173 ProcessRecord proc = null;
21174 if (process != null) {
21175 proc = findProcessLocked(process, userId, "profileControl");
21178 if (start && (proc == null || proc.thread == null)) {
21179 throw new IllegalArgumentException("Unknown process: " + process);
21183 stopProfilerLocked(null, 0);
21184 setProfileApp(proc.info, proc.processName, profilerInfo);
21185 mProfileProc = proc;
21186 mProfileType = profileType;
21187 ParcelFileDescriptor fd = profilerInfo.profileFd;
21190 } catch (IOException e) {
21193 profilerInfo.profileFd = fd;
21194 proc.thread.profilerControl(start, profilerInfo, profileType);
21198 stopProfilerLocked(proc, profileType);
21199 if (profilerInfo != null && profilerInfo.profileFd != null) {
21201 profilerInfo.profileFd.close();
21202 } catch (IOException e) {
21209 } catch (RemoteException e) {
21210 throw new IllegalStateException("Process disappeared");
21212 if (profilerInfo != null && profilerInfo.profileFd != null) {
21214 profilerInfo.profileFd.close();
21215 } catch (IOException e) {
21221 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21222 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21223 userId, true, ALLOW_FULL_ONLY, callName, null);
21224 ProcessRecord proc = null;
21226 int pid = Integer.parseInt(process);
21227 synchronized (mPidsSelfLocked) {
21228 proc = mPidsSelfLocked.get(pid);
21230 } catch (NumberFormatException e) {
21233 if (proc == null) {
21234 ArrayMap<String, SparseArray<ProcessRecord>> all
21235 = mProcessNames.getMap();
21236 SparseArray<ProcessRecord> procs = all.get(process);
21237 if (procs != null && procs.size() > 0) {
21238 proc = procs.valueAt(0);
21239 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21240 for (int i=1; i<procs.size(); i++) {
21241 ProcessRecord thisProc = procs.valueAt(i);
21242 if (thisProc.userId == userId) {
21254 public boolean dumpHeap(String process, int userId, boolean managed,
21255 String path, ParcelFileDescriptor fd) throws RemoteException {
21258 synchronized (this) {
21259 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21260 // its own permission (same as profileControl).
21261 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21262 != PackageManager.PERMISSION_GRANTED) {
21263 throw new SecurityException("Requires permission "
21264 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21268 throw new IllegalArgumentException("null fd");
21271 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21272 if (proc == null || proc.thread == null) {
21273 throw new IllegalArgumentException("Unknown process: " + process);
21276 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21277 if (!isDebuggable) {
21278 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21279 throw new SecurityException("Process not debuggable: " + proc);
21283 proc.thread.dumpHeap(managed, path, fd);
21287 } catch (RemoteException e) {
21288 throw new IllegalStateException("Process disappeared");
21293 } catch (IOException e) {
21300 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21301 String reportPackage) {
21302 if (processName != null) {
21303 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21304 "setDumpHeapDebugLimit()");
21306 synchronized (mPidsSelfLocked) {
21307 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21308 if (proc == null) {
21309 throw new SecurityException("No process found for calling pid "
21310 + Binder.getCallingPid());
21312 if (!Build.IS_DEBUGGABLE
21313 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21314 throw new SecurityException("Not running a debuggable build");
21316 processName = proc.processName;
21318 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21319 throw new SecurityException("Package " + reportPackage + " is not running in "
21324 synchronized (this) {
21325 if (maxMemSize > 0) {
21326 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21329 mMemWatchProcesses.remove(processName, uid);
21331 mMemWatchProcesses.getMap().remove(processName);
21338 public void dumpHeapFinished(String path) {
21339 synchronized (this) {
21340 if (Binder.getCallingPid() != mMemWatchDumpPid) {
21341 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21342 + " does not match last pid " + mMemWatchDumpPid);
21345 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21346 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21347 + " does not match last path " + mMemWatchDumpFile);
21350 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21351 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21355 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21356 public void monitor() {
21357 synchronized (this) { }
21360 void onCoreSettingsChange(Bundle settings) {
21361 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21362 ProcessRecord processRecord = mLruProcesses.get(i);
21364 if (processRecord.thread != null) {
21365 processRecord.thread.setCoreSettings(settings);
21367 } catch (RemoteException re) {
21373 // Multi-user methods
21376 * Start user, if its not already running, but don't bring it to foreground.
21379 public boolean startUserInBackground(final int userId) {
21380 return mUserController.startUser(userId, /* foreground */ false);
21384 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21385 return mUserController.unlockUser(userId, token, secret, listener);
21389 public boolean switchUser(final int targetUserId) {
21390 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21391 UserInfo currentUserInfo;
21392 UserInfo targetUserInfo;
21393 synchronized (this) {
21394 int currentUserId = mUserController.getCurrentUserIdLocked();
21395 currentUserInfo = mUserController.getUserInfo(currentUserId);
21396 targetUserInfo = mUserController.getUserInfo(targetUserId);
21397 if (targetUserInfo == null) {
21398 Slog.w(TAG, "No user info for user #" + targetUserId);
21401 if (!targetUserInfo.supportsSwitchTo()) {
21402 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21405 if (targetUserInfo.isManagedProfile()) {
21406 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21409 mUserController.setTargetUserIdLocked(targetUserId);
21411 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21412 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21413 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21417 void scheduleStartProfilesLocked() {
21418 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21419 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21420 DateUtils.SECOND_IN_MILLIS);
21425 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21426 return mUserController.stopUser(userId, force, callback);
21430 public UserInfo getCurrentUser() {
21431 return mUserController.getCurrentUser();
21435 public boolean isUserRunning(int userId, int flags) {
21436 if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21437 INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21438 String msg = "Permission Denial: isUserRunning() from pid="
21439 + Binder.getCallingPid()
21440 + ", uid=" + Binder.getCallingUid()
21441 + " requires " + INTERACT_ACROSS_USERS;
21443 throw new SecurityException(msg);
21445 synchronized (this) {
21446 return mUserController.isUserRunningLocked(userId, flags);
21451 public int[] getRunningUserIds() {
21452 if (checkCallingPermission(INTERACT_ACROSS_USERS)
21453 != PackageManager.PERMISSION_GRANTED) {
21454 String msg = "Permission Denial: isUserRunning() from pid="
21455 + Binder.getCallingPid()
21456 + ", uid=" + Binder.getCallingUid()
21457 + " requires " + INTERACT_ACROSS_USERS;
21459 throw new SecurityException(msg);
21461 synchronized (this) {
21462 return mUserController.getStartedUserArrayLocked();
21467 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21468 mUserController.registerUserSwitchObserver(observer);
21472 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21473 mUserController.unregisterUserSwitchObserver(observer);
21476 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21477 if (info == null) return null;
21478 ApplicationInfo newInfo = new ApplicationInfo(info);
21479 newInfo.initForUser(userId);
21483 public boolean isUserStopped(int userId) {
21484 synchronized (this) {
21485 return mUserController.getStartedUserStateLocked(userId) == null;
21489 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21491 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21495 ActivityInfo info = new ActivityInfo(aInfo);
21496 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21500 private boolean processSanityChecksLocked(ProcessRecord process) {
21501 if (process == null || process.thread == null) {
21505 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21506 if (!isDebuggable) {
21507 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21515 public boolean startBinderTracking() throws RemoteException {
21516 synchronized (this) {
21517 mBinderTransactionTrackingEnabled = true;
21518 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21519 // permission (same as profileControl).
21520 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21521 != PackageManager.PERMISSION_GRANTED) {
21522 throw new SecurityException("Requires permission "
21523 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21526 for (int i = 0; i < mLruProcesses.size(); i++) {
21527 ProcessRecord process = mLruProcesses.get(i);
21528 if (!processSanityChecksLocked(process)) {
21532 process.thread.startBinderTracking();
21533 } catch (RemoteException e) {
21534 Log.v(TAG, "Process disappared");
21541 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21543 synchronized (this) {
21544 mBinderTransactionTrackingEnabled = false;
21545 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21546 // permission (same as profileControl).
21547 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21548 != PackageManager.PERMISSION_GRANTED) {
21549 throw new SecurityException("Requires permission "
21550 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21554 throw new IllegalArgumentException("null fd");
21557 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21558 pw.println("Binder transaction traces for all processes.\n");
21559 for (ProcessRecord process : mLruProcesses) {
21560 if (!processSanityChecksLocked(process)) {
21564 pw.println("Traces for process: " + process.processName);
21567 TransferPipe tp = new TransferPipe();
21569 process.thread.stopBinderTrackingAndDump(
21570 tp.getWriteFd().getFileDescriptor());
21571 tp.go(fd.getFileDescriptor());
21575 } catch (IOException e) {
21576 pw.println("Failure while dumping IPC traces from " + process +
21577 ". Exception: " + e);
21579 } catch (RemoteException e) {
21580 pw.println("Got a RemoteException while dumping IPC traces from " +
21581 process + ". Exception: " + e);
21592 } catch (IOException e) {
21598 private final class LocalService extends ActivityManagerInternal {
21600 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
21601 int targetUserId) {
21602 synchronized (ActivityManagerService.this) {
21603 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
21604 targetPkg, intent, null, targetUserId);
21609 public String checkContentProviderAccess(String authority, int userId) {
21610 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21614 public void onWakefulnessChanged(int wakefulness) {
21615 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21619 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21620 String processName, String abiOverride, int uid, Runnable crashHandler) {
21621 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21622 processName, abiOverride, uid, crashHandler);
21626 public SleepToken acquireSleepToken(String tag) {
21627 Preconditions.checkNotNull(tag);
21629 ComponentName requestedVrService = null;
21630 ComponentName callingVrActivity = null;
21632 synchronized (ActivityManagerService.this) {
21633 if (mFocusedActivity != null) {
21634 requestedVrService = mFocusedActivity.requestedVrComponent;
21635 callingVrActivity = mFocusedActivity.info.getComponentName();
21636 userId = mFocusedActivity.userId;
21640 if (requestedVrService != null) {
21641 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21644 synchronized (ActivityManagerService.this) {
21645 SleepTokenImpl token = new SleepTokenImpl(tag);
21646 mSleepTokens.add(token);
21647 updateSleepIfNeededLocked();
21653 public ComponentName getHomeActivityForUser(int userId) {
21654 synchronized (ActivityManagerService.this) {
21655 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21656 return homeActivity == null ? null : homeActivity.realActivity;
21661 public void onUserRemoved(int userId) {
21662 synchronized (ActivityManagerService.this) {
21663 ActivityManagerService.this.onUserStoppedLocked(userId);
21668 public void onLocalVoiceInteractionStarted(IBinder activity,
21669 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21670 synchronized (ActivityManagerService.this) {
21671 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21672 voiceSession, voiceInteractor);
21677 public void notifyStartingWindowDrawn() {
21678 synchronized (ActivityManagerService.this) {
21679 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21684 public void notifyAppTransitionStarting(int reason) {
21685 synchronized (ActivityManagerService.this) {
21686 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21691 public void notifyAppTransitionFinished() {
21692 synchronized (ActivityManagerService.this) {
21693 mStackSupervisor.notifyAppTransitionDone();
21698 public void notifyAppTransitionCancelled() {
21699 synchronized (ActivityManagerService.this) {
21700 mStackSupervisor.notifyAppTransitionDone();
21705 public List<IBinder> getTopVisibleActivities() {
21706 synchronized (ActivityManagerService.this) {
21707 return mStackSupervisor.getTopVisibleActivities();
21712 public void notifyDockedStackMinimizedChanged(boolean minimized) {
21713 synchronized (ActivityManagerService.this) {
21714 mStackSupervisor.setDockedStackMinimized(minimized);
21719 public void killForegroundAppsForUser(int userHandle) {
21720 synchronized (ActivityManagerService.this) {
21721 final ArrayList<ProcessRecord> procs = new ArrayList<>();
21722 final int NP = mProcessNames.getMap().size();
21723 for (int ip = 0; ip < NP; ip++) {
21724 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21725 final int NA = apps.size();
21726 for (int ia = 0; ia < NA; ia++) {
21727 final ProcessRecord app = apps.valueAt(ia);
21728 if (app.persistent) {
21729 // We don't kill persistent processes.
21734 } else if (app.userId == userHandle && app.foregroundActivities) {
21735 app.removed = true;
21741 final int N = procs.size();
21742 for (int i = 0; i < N; i++) {
21743 removeProcessLocked(procs.get(i), false, true, "kill all fg");
21749 public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21750 if (!(target instanceof PendingIntentRecord)) {
21751 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21754 ((PendingIntentRecord) target).setWhitelistDuration(duration);
21758 private final class SleepTokenImpl extends SleepToken {
21759 private final String mTag;
21760 private final long mAcquireTime;
21762 public SleepTokenImpl(String tag) {
21764 mAcquireTime = SystemClock.uptimeMillis();
21768 public void release() {
21769 synchronized (ActivityManagerService.this) {
21770 if (mSleepTokens.remove(this)) {
21771 updateSleepIfNeededLocked();
21777 public String toString() {
21778 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21783 * An implementation of IAppTask, that allows an app to manage its own tasks via
21784 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
21785 * only the process that calls getAppTasks() can call the AppTask methods.
21787 class AppTaskImpl extends IAppTask.Stub {
21788 private int mTaskId;
21789 private int mCallingUid;
21791 public AppTaskImpl(int taskId, int callingUid) {
21793 mCallingUid = callingUid;
21796 private void checkCaller() {
21797 if (mCallingUid != Binder.getCallingUid()) {
21798 throw new SecurityException("Caller " + mCallingUid
21799 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21804 public void finishAndRemoveTask() {
21807 synchronized (ActivityManagerService.this) {
21808 long origId = Binder.clearCallingIdentity();
21810 // We remove the task from recents to preserve backwards
21811 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21812 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21815 Binder.restoreCallingIdentity(origId);
21821 public ActivityManager.RecentTaskInfo getTaskInfo() {
21824 synchronized (ActivityManagerService.this) {
21825 long origId = Binder.clearCallingIdentity();
21827 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21829 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21831 return createRecentTaskInfoFromTaskRecord(tr);
21833 Binder.restoreCallingIdentity(origId);
21839 public void moveToFront() {
21841 // Will bring task to front if it already has a root activity.
21842 final long origId = Binder.clearCallingIdentity();
21844 synchronized (this) {
21845 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21848 Binder.restoreCallingIdentity(origId);
21853 public int startActivity(IBinder whoThread, String callingPackage,
21854 Intent intent, String resolvedType, Bundle bOptions) {
21857 int callingUser = UserHandle.getCallingUserId();
21859 IApplicationThread appThread;
21860 synchronized (ActivityManagerService.this) {
21861 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21863 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21865 appThread = ApplicationThreadNative.asInterface(whoThread);
21866 if (appThread == null) {
21867 throw new IllegalArgumentException("Bad app thread " + appThread);
21870 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21871 resolvedType, null, null, null, null, 0, 0, null, null,
21872 null, bOptions, false, callingUser, null, tr);
21876 public void setExcludeFromRecents(boolean exclude) {
21879 synchronized (ActivityManagerService.this) {
21880 long origId = Binder.clearCallingIdentity();
21882 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21884 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21886 Intent intent = tr.getBaseIntent();
21888 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21890 intent.setFlags(intent.getFlags()
21891 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21894 Binder.restoreCallingIdentity(origId);
21901 * Kill processes for the user with id userId and that depend on the package named packageName
21904 public void killPackageDependents(String packageName, int userId) {
21905 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21906 if (packageName == null) {
21907 throw new NullPointerException(
21908 "Cannot kill the dependents of a package without its name.");
21911 long callingId = Binder.clearCallingIdentity();
21912 IPackageManager pm = AppGlobals.getPackageManager();
21915 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21916 } catch (RemoteException e) {
21918 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21919 throw new IllegalArgumentException(
21920 "Cannot kill dependents of non-existing package " + packageName);
21923 synchronized(this) {
21924 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21925 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21926 "dep: " + packageName);
21929 Binder.restoreCallingIdentity(callingId);